How to configure cache

Details on how cache works and configuration for each platform (Android, iOS, Backend, WEB)

How does cache work?

As in other platforms the default cache is controlled by the backend with the tag cache-control and beagle-hash, they are information that must be provided through request header, where beagle-hash is responsible for providing this hash related to the screen that has been downloaded and cache-control for the life time of this cache as reliable.

Reliable cache

A reliable cache is when its life time has not expired yet.

In this case, when verifying if there is a cache in the front and it is reliable, the screen is rendered without confirming with the server. This saves time, bandwidth and provides a fluid experience to the user.

Reliable cache its saved in the memory.

Unreliable cache

We also have the unreliable cache, that means its life time has already expired.

A unreliable cache means that when it is identified it needs to be validaded with a backend to the route with its hash.

This moment it stops being saved in the memory and it is saved in a persistent way in the disk.

Life time

The cache’s life time can have a parameter through the application’s configuration. In the standard cache implementation the life time is 300 seconds. This time can be altered if the backend sends a different time through the cache-control header, because it has priority in this configuration.

Cache re validation

When an unreliable cache is found, it must be validated with the backend. That means when searching a screen, it sends a request in the header the hash it has.

When receiving the request, the server understands that already has a version of this screen saved in the application and compares the hash value sent with the current one saved by the backend. In case they are the same, a response is sent with 304 status and without a body, indicating that the screen remains the same and that cache is reliable again.

If the hash sent by the front it is different from the one saved in the backend, a response will be sent normally with a new hash value that it must be updated in the application.

Memory and disk occupation

To avoid a memory and disk overload, both caches apply a replacement policity Least Recently Used (LRU) where the maximum quantity of the records can be also configured through the base cache class by the application. The standard values for memory and disk are 15 and 150, respectively.

Configuring and customizing the cache

There are customization allowed by default class that exists in the cache, like life time and maximum quantity of records in memory and disk.

In case the default approach does not solve the problem, the applicantion is free to replace the default implementation to another one that fits better. For that, the class responsible for the cache management needs to be in accordance with the CacheManagerProtocol protocol.

Every platform has different specifications to configure the cache.

We listed below, see:

In Android, the cache is configured when you implement the first Beagle’s configuration.

This implementation happens inside the class named AppBeagleConfig, meaning that it is inside the Beagle’s configuration class.

The cache is a Beagle’s internal class where you can define 3 properties, represented by the attributes below:

  1. enable
  2. maxAge
  3. memoryMaximumCapacity
@BeagleComponent
class AppBeagleConfig : BeagleConfig {
    override val isLoggingEnabled: Boolean = true
    override val baseUrl: String get() = "https://myapp.server.com/"
    override val environment: Environment get() = Environment.DEBUG
    override val cache: Cache = Cache(
        enabled = true,
        maxAge = 300,
        memoryMaximumCapacity = 15 // 
    )
}

Cache’s attributes

AttributeDefinition
enableboolean value that enables or disables the cache in disk and memory.
maxAgeint value of time in seconds that a memory cache will be active.
memoryMaximumCapacityInt value that represents the memory cache LRU size. It is the number of screens that will be in the memory, for example, if you define a number 15, it means 15 pages that will be in cache.

In iOS, the cache is configured when you first configure Beagle’s dependencies.

It’s allowed to change the default configuration of cache by creating a instance of a class named CacheManagerDefault. Inside this class you can define the value of 3 properties:

  1. memoryMaximumCapacity
  2. diskMaximumCapacity
  3. cacheMaxAge
let dependencies = BeagleDependencies()
let cacheManager = CacheManagerDefault(
                            dependencies: dependencies,
                            config: .init(memoryMaximumCapacity: 15,
                                          diskMaximumCapacity: 300,
                                          cacheMaxAge: 300))
dependencies.cacheManager = cacheManager
Beagle.dependencies = dependencies

It is also possible to create your own cache manager and set it to BeagleDependencies if you conform to the protocol CacheManagerProtocol.

public protocol CacheManagerProtocol {
    func addToCache(_ reference: CacheReference)
    func getReference(identifiedBy id: String) -> CacheReference?
    func isValid(reference: CacheReference) -> Bool
}

Cache’s attributes

AttributeDefinition
memoryMaximumCapacitywhole value that represents the memory cache LRU size. It is the number of screens that will be in memory. For example, if you define a number 15, it means 15 pages that will be in cache.
diskMaximumCapacityWhole value that represents the memory cache LRU size. It is the number of screens that will be in the memory. For example, if you define a number 15, it means 15 pages that will be in cache.
cacheMaxAgewhole time value in seconds that the memory cache is active.

In the backend this functionality is only supported if you use the [started library](https://docs-beta.usebeagle.io/backend/get-started/creating-a-project-from-scratch/#Step 3: Include starter dependency)

The cache was created to optimize the response of a request in terms of size and BFF’s time, when the return is the same as the previous one. The input in this cache last until the server is redeployed or the client installed again.

To make this configuration:

  1. Search inside the ‌src/main/resources folder for the file application.properties
  2. If you don’t have it, you can install now.

In case the key is not listed in your file, it means that the standard configuration will be applied automatically.

beagle.cache.endpoint.exclude=/imagebeagle.cache.enabled=false​

In the list below, you will find what are the available properties and which configuration can be altered.

KeyDescriptionDefault
beagle.cache.enabledFlag indicating if the cache mechanism is enabled or not.true
beagle.cache.endpoint.includeEndpoints list to be cached. It accepts regular expressions according to java.util.regex.Pattern throughkotlin.text.Regex.All (<=1.0.2) None (>=1.1.0)
beagle.cache.endpoint.excludeEndpoints list to not be cached. It accepts regular expressions according tojava.util.regex.Pattern. through kotlin.text.Regex. The exclusion is a priority.None
beagle.cache.endpoint.ttl (>=1.1.0)Key values pair, where the key is an endpoint like a string and a value is the duration. The duration is a number following the abbreviated unit (s, m, h, etc) to populate the header valueCache-control: max-age to this endpoint. The endpoint needs to be included. Included enpoints have a 30s duration by default. Durations shorter than a second will be zero, by the Cache-control: max-age definition.None

On web, the cache is configured when Beagle’s Web initial configuration is defined on the strategy parameter, which is one of BeagleModule parameters (if you’re using Angular) or createBeagleUIService\ (if you’re using React).

By default, the cache comes enabled with beagle-with-fallback-to-cache strategy, however the beagle-cache-only strategy can also be used to implement Beagle’s cache protocol.

Check below the examples on how to change beagle-with-fallback-to-cache, which is default forbeagle-cache-only.

Example of configuration for Angular:

@BeagleModule({
  baseUrl: 'http://localhost:4200/assets',
  module: {
    path: './beagle-components.module',
    name: 'BeagleComponentsModule',
  },
  components: {
    // Associate every beagle component to your angular component. 
  },
  strategy: 'beagle-cache-only'
})
export class Beagle { }

Example of configuration for React:

export default createBeagleUIService({
  baseUrl: "",
  components: {},
  strategy: 'beagle-cache-only'
})