generated from apollographql/typescript-repo-template
-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extend cache TTL for responses with last-modified (#106)
Some cache entries can be used even after they "expire", if they have a response header like "etag" or "last-modified" that lets you run a special HTTP request that can get a 304 response (to mean "reuse the data you have" rather than needing to fully send it again). So we have special logic to keep those responses in our cache for longer... but that logic only looks for etag, not last-modified. So now we look for both. As part of this, add a bunch of related comments and documentation. In order to make the test of this functionality fail without the fix, it needs to use a KeyValueCache that actually observes TTL, so switch to the one we use in apollo-server. Note that this reveals that some existing tests were actually reading cache values after TTL which resulted in some minor changes like `age: 0` instead of missing `age`. Fixes #34.
- Loading branch information
Showing
7 changed files
with
152 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@apollo/datasource-rest': minor | ||
--- | ||
|
||
Previously, RESTDataSource doubled the TTL used with its shared header-sensitive cache when it may be able to use the cache entry after it goes stale because it contained the `ETag` header; for these cache entries, RESTDataSource can set the `If-None-Match` header when sending the REST request and the server can return a 304 response telling RESTDataSource to reuse the old response from its cache. Now, RESTDataSource also extends the TTL for responses with the `Last-Modified` header (which it can validate with `If-Modified-Since`). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ codesandbox | |
concat | ||
datasource | ||
direnv | ||
Fakeable | ||
falsey | ||
httpcache | ||
isplainobject | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// The default AS cache (`InMemoryLRUCache`) uses `lru-cache` internally, which | ||
// we've had issues mocking timers for. Presumably this has something to do with | ||
// the way that `lru-cache` grabs its `perf` function: | ||
// https://github.com/isaacs/node-lru-cache/blob/118a078cc0ea3a17f7b2ff4caf04e6aa3a33b136/index.js#L1-L6 | ||
// This test suite already mocks `Date` (because | ||
// `ApolloServerPluginResponseCache` uses it internally), so we used that for | ||
// time calculation in this mock cache as well. | ||
// | ||
// (Borrowed from apollo-server.) | ||
export class FakeableTTLTestingCache { | ||
constructor( | ||
private cache: Map< | ||
string, | ||
{ value: string; deadline: number | null } | ||
> = new Map(), | ||
) {} | ||
|
||
async get(key: string) { | ||
const entry = this.cache.get(key); | ||
if (!entry) return undefined; | ||
if (entry.deadline && entry.deadline <= Date.now()) { | ||
await this.delete(key); | ||
return undefined; | ||
} | ||
return entry.value; | ||
} | ||
|
||
async set( | ||
key: string, | ||
value: string, | ||
{ ttl }: { ttl: number | null } = { ttl: null }, | ||
) { | ||
this.cache.set(key, { | ||
value, | ||
deadline: ttl ? Date.now() + ttl * 1000 : null, | ||
}); | ||
} | ||
|
||
async delete(key: string) { | ||
this.cache.delete(key); | ||
} | ||
|
||
isEmpty() { | ||
// Trigger the get()-time TTL cleanup. | ||
for (const key of this.cache.keys()) { | ||
this.get(key); | ||
} | ||
return this.cache.size === 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.