UNPKG

1.92 kBJavaScriptView Raw
1const noop = () => Promise.resolve();
2// @ts-ignore
3export function wrapRequest(state, request, options) {
4 return state.retryLimiter.schedule(doRequest, state, request, options);
5}
6// @ts-ignore
7async function doRequest(state, request, options) {
8 const isWrite = options.method !== "GET" && options.method !== "HEAD";
9 const isSearch = options.method === "GET" && options.url.startsWith("/search/");
10 const isGraphQL = options.url.startsWith("/graphql");
11 const retryCount = ~~options.request.retryCount;
12 const jobOptions = retryCount > 0 ? { priority: 0, weight: 0 } : {};
13 if (state.clustering) {
14 // Remove a job from Redis if it has not completed or failed within 60s
15 // Examples: Node process terminated, client disconnected, etc.
16 // @ts-ignore
17 jobOptions.expiration = 1000 * 60;
18 }
19 // Guarantee at least 1000ms between writes
20 // GraphQL can also trigger writes
21 if (isWrite || isGraphQL) {
22 await state.write.key(state.id).schedule(jobOptions, noop);
23 }
24 // Guarantee at least 3000ms between requests that trigger notifications
25 if (isWrite && state.triggersNotification(options.url)) {
26 await state.notifications.key(state.id).schedule(jobOptions, noop);
27 }
28 // Guarantee at least 2000ms between search requests
29 if (isSearch) {
30 await state.search.key(state.id).schedule(jobOptions, noop);
31 }
32 const req = state.global.key(state.id).schedule(jobOptions, request, options);
33 if (isGraphQL) {
34 const res = await req;
35 if (res.data.errors != null &&
36 // @ts-ignore
37 res.data.errors.some(error => error.type === "RATE_LIMITED")) {
38 const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), {
39 headers: res.headers,
40 data: res.data
41 });
42 throw error;
43 }
44 }
45 return req;
46}