Managing cache

Caching is a mechanism that enables an application to limit network usage by reusing previously downloaded resources without requesting them again of the web service. A cache is represented by the Cache interface in the content API and is able to store and retrieve resources through a unique string key. Each cached resource is represented by a CacheEntry instance that contains the real cached data, accessible with the getData() method.

The Content API provides out-of-the-box Cache implementations:

  • FileCache: each resource is stored in a dedicated file
  • NoCache: a special implementation that does not cache any resources

The cache system is driven by the web service through particular headers that act like cache directives. These informations are automatically stored in the CacheEntry.

Here are the two major concepts of the cache metadata :

  • Expiration: a resource sent from the server have an expiration date
  • Change verification: the cache can check if the resource has changed on the server

When requesting a resource with a ContentQuery, the ContentManager first checks if the desired resource is available in cache.

Understanding cache data update

When performing a request, if a resource is in cache, a CacheEntry representing the resource is created with the raw data and metadata of the resource. The metadata will be analysed to determine what to do with the cache:

  • No data in cache: if the resource is not present in cache, the network layer is used to get the resource from the web service. The anwsered resource is then put in the cache for later use. A final ContentResponse is sent to the screen that originated the request.
  • Data in cache are expired: the TTL has expired. The cache entry is left aside while the resource is downloaded again as if it was not in the cache. Note that no intermediate ContentResponse is sent to the screen that originated the request. The final ContentResponse will be sent after the download of the data (or a ContentError if there was an error in the server side).
  • Data in cache are not expired and do not need to be refreshed: the TTL and the soft TTL of the resource are not expired, the resource is considered as still valid (by default, the soft TTL is the same as the TTL). A final ContentResponse is sent to the screen that originated the request, without requesting the network.
  • Data in cache needs to be refreshed: a first intermediate ContentResponse is sent to the screen that originated the request. The screen is able display data while the final response is being requested. After the download, a final ContentResponse will be sent (or a ContentError if there was an error in the server side).

When the cache has expired or need to be refreshed, a request will be done through the network. The cache will be updated depending on the server response:

  • The server answers ‘Not Modified’: the cache update the metadata of the original CacheEntry.
  • The server sends a complete response: the cache entry is entirely updated.
  • A server error occurs: nothing is done on the cache.

Handling network errors

When an error has occured in the network, e.g. when no network is available, a ContentError is sent to the screen that originated the request. ContentError contains information about the cause of the failure.

Some convenience methods can be useful to help to find the origin of the problem:

  • isAuthenticationError(): the server response is 401 or 403
  • isNetworkError(): unexpected error occurs in the network implementation
  • isNoConnectionError(): the device has lost the internet connection.
  • isParseError(): data from server cannot be parsed by the application
  • isServerError(): the server response does not have a 2XX, 401 or 403 HTTP status code.
  • isTimeoutError(): the server takes too long time to answer

Managing client cache from the server

HTTP 1.1 specifications standardizes cache control headers. Server responses can contain cache metadata about sent data through HTTP Headers.

Three caching modes exist and could be used in different contexts.

No-Cache

The web service can disable client cache for the requested resource.

Response Headers

Cache-Control: none

Expiration

The web service can explicitely set an expiration date (headers are sorted by priority). This is perfect for static resources that do not need to be often changed and are not important.

Response Headers

Expires: <date>
Cache-Control: max-age=<delay> //time-to-live in seconds

Warning

If an image expires in 30 days, the client will use this image during 30 days even if the server has changed the image. Any changes will not be visible for 30 days.

Validation

Server responses can contain specific headers that tag the requested resource. These tags can be reused later in new client requests to provide a way for the server to check if the resource has changed since the tag was emitted.

This mode is perfect for dynamic data that need to be changed frequently. If data is a list, prefer using Last-Modified date. If data is a model, prefer using ETag.

Response Headers

ETag: <checksum of the resource>
Date: <date>

Request Headers

The client requests the data that has changed from the server since the last query.

If-None-Match: <Etag> //etag of the resource read from cache metadata
If-Since-Modified: <date> //last date of the resource received from the server, read from cache metadata

Reading from cache in Offline mode

In some applications, if no network is connected and the data in cache is expired, developers want to use the expired data anyway in order to display something on the screen. In such a situation, a new network needs to be implemented to mock a 304 Not Modified network response. This way the expired resource will be used.