requestDidEnd only called after the last patch resolves

This commit is contained in:
clarencenpy 2018-08-08 16:30:27 -07:00
parent 1fa4105403
commit 927ca65ec7
2 changed files with 12 additions and 8 deletions

View file

@ -483,7 +483,7 @@ export async function runHttpQuery(
const isDeferred = isDeferredGraphQLResponse(graphqlResponse);
let initialResponse: ExecutionResult; // We need this check for and and throw errors
let initialResponse: ExecutionResult; // We need this check for and throw errors
if (isDeferred) {
initialResponse = (graphqlResponse as DeferredGraphQLResponse)
@ -520,7 +520,9 @@ export async function runHttpQuery(
};
}
// TODO: Handle defer in batched queries. This is a little awkward now since we need a separate HTTP connection to stream patches.
// TODO: Handle defer in batched queries.
// This is a little awkward now since we need a separate HTTP connection
// to stream patches per query.
return {
graphqlResponse: prettyJSONStringify(responses),
responseInit,
@ -551,6 +553,8 @@ function graphqlResponseToAsyncIterable(
fromGraphQLError(error),
);
}
// Call requestDidEnd when the last patch is resolved
if (done) result.requestDidEnd();
return { value: prettyJSONStringify(value), done };
});
}

View file

@ -46,9 +46,9 @@ export interface GraphQLResponse {
}
export interface DeferredGraphQLResponse {
errors?: Array<GraphQLError & object>;
initialResponse: GraphQLResponse;
deferredPatches: AsyncIterable<ExecutionPatchResult>;
requestDidEnd: () => void;
}
export function isDeferredGraphQLResponse(
@ -278,7 +278,6 @@ function doRunQuery(
let patches: AsyncIterable<ExecutionPatchResult> | undefined;
if (isDeferredExecutionResult(result)) {
// TODO: Deferred execution should be disabled if transport does not support it
executionResult = result.initialResult;
patches = result.deferredPatches;
} else {
@ -312,6 +311,7 @@ function doRunQuery(
return {
initialResponse: response,
deferredPatches: patches!,
requestDidEnd,
};
} else {
return response;
@ -327,16 +327,16 @@ function doRunQuery(
throw err;
})
.then((graphqlResponse: GraphQLResponse | DeferredGraphQLResponse) => {
// For deferred queries, only the initial response gets presented to the
// extension stack
// For deferred queries, pass the requestDidEnd callback as part of the
// AsyncIterable so that it only gets called after all
// the patches have been resolved.
if (isDeferredGraphQLResponse(graphqlResponse)) {
const response = extensionStack.willSendResponse({
graphqlResponse: graphqlResponse.initialResponse,
});
requestDidEnd();
return {
...graphqlResponse,
initialResponse: response.graphqlResponse,
deferredPatches: graphqlResponse.deferredPatches,
};
} else {
const response = extensionStack.willSendResponse({