Skip to content

Commit db98fd5

Browse files
committed
use timeout deferred making sure promise is not hanging
1 parent d0919d7 commit db98fd5

File tree

1 file changed

+12
-13
lines changed

1 file changed

+12
-13
lines changed

packages/runtime/src/plugins/useUpstreamTimeout.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { subgraphNameByExecutionRequest } from '@graphql-mesh/fusion-runtime';
33
import { UpstreamErrorExtensions } from '@graphql-mesh/transport-common';
44
import { getHeadersObj } from '@graphql-mesh/utils';
55
import {
6+
createDeferred,
67
createGraphQLError,
78
ExecutionRequest,
9+
ExecutionResult,
810
isAsyncIterable,
911
isPromise,
1012
} from '@graphql-tools/utils';
@@ -52,6 +54,13 @@ export function useUpstreamTimeout<TContext extends Record<string, any>>(
5254
timeoutSignal,
5355
);
5456
}
57+
const timeoutDeferred = createDeferred<ExecutionResult>();
58+
function rejectDeferred() {
59+
timeoutDeferred.reject(timeoutSignal?.reason);
60+
}
61+
timeoutSignal.addEventListener('abort', rejectDeferred, {
62+
once: true,
63+
});
5564
const signals: AbortSignal[] = [];
5665
signals.push(timeoutSignal);
5766
if (executionRequest.signal) {
@@ -67,19 +76,7 @@ export function useUpstreamTimeout<TContext extends Record<string, any>>(
6776
if (!isPromise(res$)) {
6877
return res$;
6978
}
70-
return Promise.race([
71-
new Promise<never>((_, reject) => {
72-
if (timeoutSignal.aborted) {
73-
return reject(timeoutSignal.reason);
74-
}
75-
timeoutSignal.addEventListener(
76-
'abort',
77-
() => reject(timeoutSignal.reason),
78-
{ once: true },
79-
);
80-
}),
81-
res$,
82-
])
79+
return Promise.race([timeoutDeferred.promise, res$])
8380
.then((result) => {
8481
if (isAsyncIterable(result)) {
8582
return {
@@ -119,6 +116,8 @@ export function useUpstreamTimeout<TContext extends Record<string, any>>(
119116
throw e;
120117
})
121118
.finally(() => {
119+
timeoutDeferred.resolve(undefined as any);
120+
timeoutSignal.removeEventListener('abort', rejectDeferred);
122121
// Remove from the map after used so we don't see it again
123122
errorExtensionsByExecRequest.delete(executionRequest);
124123
timeoutSignalsByExecutionRequest.delete(executionRequest);

0 commit comments

Comments
 (0)