Skip to content

Commit

Permalink
fix(service-worker): cache opaque responses when requests exceeds tim…
Browse files Browse the repository at this point in the history
…eout threshold (#30977)

PR Close #30977
  • Loading branch information
gkalpak authored and alxhub committed Jun 27, 2019
1 parent d7be38f commit 93abc35
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
7 changes: 4 additions & 3 deletions packages/service-worker/worker/src/data.ts
Expand Up @@ -378,7 +378,7 @@ export class DataGroup {

// If the network fetch times out or errors, fall back on the cache.
if (res === undefined) {
ctx.waitUntil(this.safeCacheResponse(req, networkFetch));
ctx.waitUntil(this.safeCacheResponse(req, networkFetch, true));

// Ignore the age, the network response will be cached anyway due to the
// behavior of freshness.
Expand Down Expand Up @@ -434,9 +434,10 @@ export class DataGroup {
}
}

private async safeCacheResponse(req: Request, res: Promise<Response>): Promise<void> {
private async safeCacheResponse(req: Request, res: Promise<Response>, okToCacheOpaque?: boolean):
Promise<void> {
try {
await this.cacheResponse(req, await res, await this.lru());
await this.cacheResponse(req, await res, await this.lru(), okToCacheOpaque);
} catch {
// TODO: handle this error somehow?
}
Expand Down
30 changes: 30 additions & 0 deletions packages/service-worker/worker/test/data_spec.ts
Expand Up @@ -259,6 +259,36 @@ import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope';
expect(await makeRequest(scope, '/refresh/data')).toEqual('this is refreshed data');
serverUpdate.assertNoOtherRequests();
});

it('caches opaque responses on refresh', async() => {
// Make the initial request and populate the cache.
expect(await makeRequest(scope, '/fresh/data')).toBe('this is fresh data');
server.assertSawRequestFor('/fresh/data');
server.clearRequests();

// Update the server state and pause the server, so the next request times out.
scope.updateServerState(serverUpdate);
serverUpdate.pause();
const [res, done] =
makePendingRequest(scope, new MockRequest('/fresh/data', {mode: 'no-cors'}));

// The network request times out after 1,000ms and the cached response is returned.
await serverUpdate.nextRequest;
scope.advance(2000);
expect(await res).toBe('this is fresh data');

// Unpause the server to allow the network request to complete and be cached.
serverUpdate.unpause();
await done;

// Pause the server to force the cached (opaque) response to be returned.
serverUpdate.pause();
const [res2] = makePendingRequest(scope, '/fresh/data');
await serverUpdate.nextRequest;
scope.advance(2000);

expect(await res2).toBe('');
});
});
});
})();
Expand Down

0 comments on commit 93abc35

Please sign in to comment.