Skip to content

Commit

Permalink
Add documentation for preemptive background refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
kibertoad committed Jan 13, 2024
1 parent 4076852 commit ff7bb8f
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions README.md
Expand Up @@ -408,13 +408,13 @@ Note that Loaders are generally recommended over ManualCaches, as they offer bet
In case you are handling very heavy load and want to achieve highest possible performance, you can avoid asynchronous retrieval (and unnecessary Promise overhead) altogether in case there is a value already available in in-memory cache. Here is the example:

```ts
const loader = new Loader<string>({
const loader = new Loader<MyValueType>({
inMemoryCache: {
// configuration here
},

// this cache will be checked if in-memory one returns undefined
asyncCache: new RedisCache(ioRedis, {
asyncCache: new RedisCache<MyValueType>(ioRedis, {
// configuration here
}),
dataSources: [new MyDataSource()],
Expand All @@ -431,20 +431,40 @@ Note that this will only work with truthy values. If you expect to get significa

```ts
let cachedValue: MyValueType | undefined | null
cachedValue = loader.getInMemoryOnly('someCacheKey')
cachedValue = loader.getInMemoryOnly('key')

if (cachedValue === undefined) {
cachedValue = await loader.getAsyncOnly('someCacheKey')
cachedValue = await loader.getAsyncOnly('key')
}
```

If you are unsure, whether you are caching significant amount of falsy or empty (null/empty string) values, you can enable cache statistics for discovering this data. See section "Cache statistics" for how to set that up.

### Preemptive background refresh

ToDo
In case some of your datasource calls are very expensive, and you want to reduce response latency, you can start preemptively refreshing your cache in background while still serving not-yet-stale current data. In order to do so, you need to set parameter `ttlLeftBeforeRefreshInMsecs`.
For in-memory cache:
```ts
const operation = new Loader<string>({
inMemoryCache: {
cacheId: 'some-cache',
ttlInMsecs: 1000 * 60,
ttlLeftBeforeRefreshInMsecs: 1000 * 20, // this means that when there is a GET operation for the cache entry, and it has less than 20 seconds of TTL left, background refresh for this entry will start
},
// the rest of loader configuration
})
```

For Redis cache:
```ts
const asyncCache = new RedisCache<string>(redis, {
ttlInMsecs: 1000 * 60,
ttlLeftBeforeRefreshInMsecs: 1000 * 20,
})// this means that when there is a GET operation for the cache entry, and it has less than 20 seconds of TTL left, background refresh for this entry will start
```

Note that bulk operations (`getMany()` do not support preemptive background refresh)
Note that there is overhead involved in performing refresh checks (especially for Redis). Always measure performance before and after enabling preemptive refresh in order to determine, whether it improves or worsens the performance of your system.
Bulk operations (`getMany()`) do not support preemptive background refresh.

## Group operations

Expand Down

0 comments on commit ff7bb8f

Please sign in to comment.