From 1479af978cd2bbe4ee9f1ca9682684b8e5135fa7 Mon Sep 17 00:00:00 2001 From: Youssef El Houti Date: Tue, 5 Dec 2023 11:24:31 +0100 Subject: [PATCH] feat(service-worker): finish implementation of refreshAhead feature (#53356) Copy and document the refreshAhead option that allows to refresh cache entries before they expire. This allows to mark cached entries as stale while still retruning them until maxAge in case of service outage. Closes #46729 PR Close #53356 --- .../content/ecosystem/service-workers/config.md | 17 +++++++++++++++++ .../service-worker/config/index.api.md | 1 + packages/service-worker/config/schema.json | 4 ++++ packages/service-worker/config/src/generator.ts | 2 ++ packages/service-worker/config/src/in.ts | 1 + .../config/test/generator_spec.ts | 9 +++++++++ 6 files changed, 34 insertions(+) diff --git a/adev/src/content/ecosystem/service-workers/config.md b/adev/src/content/ecosystem/service-workers/config.md index da5239f6ad7..ea752174c25 100644 --- a/adev/src/content/ecosystem/service-workers/config.md +++ b/adev/src/content/ecosystem/service-workers/config.md @@ -197,6 +197,7 @@ export interface DataGroup { maxSize: number; maxAge: string; timeout?: string; + refreshAhead?: string; strategy?: 'freshness' | 'performance'; }; cacheQueryOptions?: { @@ -270,6 +271,22 @@ The network timeout is how long the Angular service worker waits for the network For example, the string `5s30u` translates to five seconds and 30 milliseconds of network timeout. + +##### `refreshAhead` + +This duration string specifies the time ahead of the expiration of a cached resource when the Angular service worker should proactively attempt to refresh the resource from the network. +The `refreshAhead` duration is an optional configuration that determines how much time before the expiration of a cached response the service worker should initiate a request to refresh the resource from the network. + +| Suffixes | Details | +|:--- |:--- | +| `d` | Days | +| `h` | Hours | +| `m` | Minutes | +| `s` | Seconds | +| `u` | Milliseconds | + +For example, the string `1h30m` translates to one hour and 30 minutes ahead of the expiration time. + ##### `strategy` The Angular service worker can use either of two caching strategies for data resources. diff --git a/goldens/public-api/service-worker/config/index.api.md b/goldens/public-api/service-worker/config/index.api.md index bd5a35187d1..79429bdfbd9 100644 --- a/goldens/public-api/service-worker/config/index.api.md +++ b/goldens/public-api/service-worker/config/index.api.md @@ -44,6 +44,7 @@ export interface DataGroup { maxSize: number; maxAge: Duration; timeout?: Duration; + refreshAhead?: Duration; strategy?: 'freshness' | 'performance'; cacheOpaqueResponses?: boolean; }; diff --git a/packages/service-worker/config/schema.json b/packages/service-worker/config/schema.json index 4b02f9772ba..fb1ab0cf368 100644 --- a/packages/service-worker/config/schema.json +++ b/packages/service-worker/config/schema.json @@ -119,6 +119,10 @@ "type": "string", "description": "This duration string specifies the network timeout. The network timeout is how long the Angular service worker will wait for the network to respond before using a cached response, if configured to do so. 'timeout' is a duration string, using the following unit suffixes: d= days, h= hours, m= minutes, s= seconds, u= milliseconds. For example, the string '5s30u' will translate to five seconds and 30 milliseconds of network timeout." }, + "refreshAhead": { + "type": "string", + "description": "This duration string specifies the time ahead of the expiration of a cached resource when the Angular service worker should proactively attempt to refresh the resource from the network. The `refreshAhead` duration is an optional configuration that determines how much time before the expiration of a cached response the service worker should initiate a request to refresh the resource from the network." + }, "strategy": { "enum": [ "freshness", diff --git a/packages/service-worker/config/src/generator.ts b/packages/service-worker/config/src/generator.ts index 14acf2f682f..8382eaa9632 100644 --- a/packages/service-worker/config/src/generator.ts +++ b/packages/service-worker/config/src/generator.ts @@ -103,6 +103,8 @@ export class Generator { maxSize: group.cacheConfig.maxSize, maxAge: parseDurationToMs(group.cacheConfig.maxAge), timeoutMs: group.cacheConfig.timeout && parseDurationToMs(group.cacheConfig.timeout), + refreshAheadMs: + group.cacheConfig.refreshAhead && parseDurationToMs(group.cacheConfig.refreshAhead), cacheOpaqueResponses: group.cacheConfig.cacheOpaqueResponses, cacheQueryOptions: buildCacheQueryOptions(group.cacheQueryOptions), version: group.version !== undefined ? group.version : 1, diff --git a/packages/service-worker/config/src/in.ts b/packages/service-worker/config/src/in.ts index f48c37e6cda..76d877e2912 100644 --- a/packages/service-worker/config/src/in.ts +++ b/packages/service-worker/config/src/in.ts @@ -56,6 +56,7 @@ export interface DataGroup { maxSize: number; maxAge: Duration; timeout?: Duration; + refreshAhead?: Duration; strategy?: 'freshness' | 'performance'; cacheOpaqueResponses?: boolean; }; diff --git a/packages/service-worker/config/test/generator_spec.ts b/packages/service-worker/config/test/generator_spec.ts index 48536899175..ef146471550 100644 --- a/packages/service-worker/config/test/generator_spec.ts +++ b/packages/service-worker/config/test/generator_spec.ts @@ -100,6 +100,7 @@ describe('Generator', () => { maxAge: 259200000, timeoutMs: 60000, version: 1, + refreshAheadMs: undefined, cacheOpaqueResponses: undefined, cacheQueryOptions: {ignoreVary: true}, }, @@ -351,6 +352,7 @@ describe('Generator', () => { maxSize: 100, maxAge: 259200000, timeoutMs: undefined, + refreshAheadMs: undefined, version: 1, cacheOpaqueResponses: undefined, cacheQueryOptions: {ignoreVary: true}, @@ -362,6 +364,7 @@ describe('Generator', () => { maxSize: 100, maxAge: 259200000, timeoutMs: undefined, + refreshAheadMs: undefined, version: 1, cacheOpaqueResponses: false, cacheQueryOptions: {ignoreVary: true}, @@ -373,6 +376,7 @@ describe('Generator', () => { maxSize: 100, maxAge: 259200000, timeoutMs: undefined, + refreshAheadMs: undefined, version: 1, cacheOpaqueResponses: true, cacheQueryOptions: {ignoreVary: true}, @@ -384,6 +388,7 @@ describe('Generator', () => { maxSize: 100, maxAge: 259200000, timeoutMs: undefined, + refreshAheadMs: undefined, version: 1, cacheOpaqueResponses: undefined, cacheQueryOptions: {ignoreVary: true}, @@ -395,6 +400,7 @@ describe('Generator', () => { maxSize: 100, maxAge: 259200000, timeoutMs: undefined, + refreshAheadMs: undefined, version: 1, cacheOpaqueResponses: false, cacheQueryOptions: {ignoreVary: true}, @@ -406,6 +412,7 @@ describe('Generator', () => { maxSize: 100, maxAge: 259200000, timeoutMs: undefined, + refreshAheadMs: undefined, version: 1, cacheOpaqueResponses: true, cacheQueryOptions: {ignoreVary: true}, @@ -448,6 +455,7 @@ describe('Generator', () => { maxSize: 100, strategy: 'performance', timeout: '1m', + refreshAhead: '1h', }, cacheQueryOptions: {ignoreSearch: false}, }, @@ -477,6 +485,7 @@ describe('Generator', () => { maxSize: 100, maxAge: 259200000, timeoutMs: 60000, + refreshAheadMs: 3600000, version: 1, cacheOpaqueResponses: undefined, cacheQueryOptions: {ignoreSearch: false, ignoreVary: true},