Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't write to persisted query cache until execution will begin. #2227

Merged
merged 2 commits into from
Jan 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### vNEXT

- Switch from `json-stable-stringify` to `fast-json-stable-stringify`. [PR #2065](https://github.com/apollographql/apollo-server/pull/2065)
- Don't write to the persisted query cache until execution will begin. [PR #2227](https://github.com/apollographql/apollo-server/pull/2227)

### v2.3.1

Expand Down
26 changes: 21 additions & 5 deletions packages/apollo-server-core/src/requestPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
} from 'apollo-server-plugin-base';

import { Dispatcher } from './utils/dispatcher';
import { KeyValueCache } from 'apollo-server-caching';

export {
GraphQLRequest,
Expand Down Expand Up @@ -102,6 +103,7 @@ export async function processGraphQLRequest<TContext>(

let queryHash: string;

let persistedQueryCache: KeyValueCache | undefined;
let persistedQueryHit = false;
let persistedQueryRegister = false;

Expand All @@ -116,10 +118,14 @@ export async function processGraphQLRequest<TContext>(
);
}

// We'll store a reference to the persisted query cache so we can actually
// do the write at a later point in the request pipeline processing.
persistedQueryCache = config.persistedQueries.cache;

queryHash = extensions.persistedQuery.sha256Hash;

if (query === undefined) {
query = await config.persistedQueries.cache.get(`apq:${queryHash}`);
query = await persistedQueryCache.get(`apq:${queryHash}`);
if (query) {
persistedQueryHit = true;
} else {
Expand All @@ -134,11 +140,11 @@ export async function processGraphQLRequest<TContext>(
);
}

// We won't write to the persisted query cache until later.
// Defering the writing gives plugins the ability to "win" from use of
// the cache, but also have their say in whether or not the cache is
// written to (by interrupting the request with an error).
persistedQueryRegister = true;

Promise.resolve(
config.persistedQueries.cache.set(`apq:${queryHash}`, query),
).catch(console.warn);
}
} else if (query) {
// FIXME: We'll compute the APQ query hash to use as our cache key for
Expand Down Expand Up @@ -212,6 +218,16 @@ export async function processGraphQLRequest<TContext>(
>,
);

// Now that we've gone through the pre-execution phases of the request
// pipeline, and given plugins appropriate ability to object (by throwing
// an error) and not actually write, we'll write to the cache if it was
// determined earlier in the request pipeline that we should do so.
if (persistedQueryRegister && persistedQueryCache) {
Promise.resolve(persistedQueryCache.set(`apq:${queryHash}`, query)).catch(
console.warn,
);
}

const executionDidEnd = await dispatcher.invokeDidStartHook(
'executionDidStart',
requestContext as WithRequired<
Expand Down