mirror of
https://github.com/wassname/talk.git
synced 2026-07-10 00:35:56 +08:00
Try a promise oriented fetch timeout for perspective
If this mitigates issues of failed requests, this means we can switch over to this version of time out based fetch requests. CORL-1277
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import AbortController from "abort-controller";
|
||||
import http from "http";
|
||||
import https from "https";
|
||||
import { capitalize } from "lodash";
|
||||
import { clearLongTimeout } from "long-settimeout";
|
||||
import fetch, { RequestInit, Response } from "node-fetch";
|
||||
import fetch, { RequestInfo, RequestInit, Response } from "node-fetch";
|
||||
import { URL } from "url";
|
||||
|
||||
import { version } from "coral-common/version";
|
||||
@@ -58,6 +59,83 @@ export function generateFetchOptions(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fetch request with a time out.
|
||||
* Inspired by: https://www.lowmess.com/blog/fetch-with-timeout/
|
||||
*
|
||||
* @param name gives the request headers user agent a name
|
||||
* @param url the url you want to make a request against
|
||||
* @param options fetch options, will override preset defaults
|
||||
* @param timeMs time in milliseconds to wait for response
|
||||
*/
|
||||
export const fetchWithTimeout = (
|
||||
name: string,
|
||||
url: RequestInfo,
|
||||
options = {},
|
||||
timeMs?: number
|
||||
) => {
|
||||
const controller = new AbortController();
|
||||
|
||||
// Create HTTP agents to improve connection performance.
|
||||
const agents = {
|
||||
https: new https.Agent({
|
||||
keepAlive: true,
|
||||
}),
|
||||
http: new http.Agent({
|
||||
keepAlive: true,
|
||||
}),
|
||||
};
|
||||
|
||||
// agent will select the correct agent to use for reusing the agent.
|
||||
const agent = (agentUrl: URL) =>
|
||||
agentUrl.protocol === "http:" ? agents.http : agents.https;
|
||||
|
||||
const defaultHeaders = {
|
||||
"User-Agent": `Coral ${capitalize(name)}/${version}`,
|
||||
};
|
||||
|
||||
const config: FetchOptions = {
|
||||
agent,
|
||||
headers: {
|
||||
...defaultHeaders,
|
||||
},
|
||||
// Limit response sizes to 2MB of response data. 1e6B is 1MB.
|
||||
size: 2e6,
|
||||
// Do not follow redirects automatically, and do not error if we
|
||||
// encounter one. We'll treat the response from the request as the
|
||||
// endpoints final response.
|
||||
redirect: "manual",
|
||||
// Attach the controller signal to abort the request after the timeout
|
||||
// is reached.
|
||||
signal: controller.signal,
|
||||
|
||||
...options,
|
||||
};
|
||||
|
||||
const time = timeMs ? timeMs : 10000;
|
||||
const timeOut = setTimeout(() => {
|
||||
controller.abort();
|
||||
}, time);
|
||||
|
||||
return fetch(url, config)
|
||||
.then((response) => {
|
||||
clearTimeout(timeOut);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
return response;
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.name === "AbortError") {
|
||||
throw new Error("fetch response timed out");
|
||||
}
|
||||
|
||||
throw new Error(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
export const createFetch = ({
|
||||
name,
|
||||
options: { headers: defaultBaseHeaders = {}, ...defaultOptions } = {},
|
||||
|
||||
@@ -4,9 +4,7 @@ import { URL } from "url";
|
||||
import { TOXICITY_ENDPOINT_DEFAULT } from "coral-common/constants";
|
||||
import { LanguageCode } from "coral-common/helpers";
|
||||
import { getURLWithCommentID } from "coral-server/models/story";
|
||||
import { createFetch } from "coral-server/services/fetch";
|
||||
|
||||
const fetch = createFetch({ name: "perspective" });
|
||||
import { fetchWithTimeout } from "coral-server/services/fetch";
|
||||
|
||||
/**
|
||||
* Language is the language key that is supported by the Perspective API in the
|
||||
@@ -137,14 +135,18 @@ export async function sendToPerspective(
|
||||
|
||||
try {
|
||||
// Create the request and send it.
|
||||
const res = await fetch(url.toString(), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
const res = await fetchWithTimeout(
|
||||
"perspective",
|
||||
url.toString(),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body,
|
||||
},
|
||||
timeout,
|
||||
body,
|
||||
});
|
||||
timeout
|
||||
);
|
||||
if (!res.ok) {
|
||||
return {
|
||||
ok: res.ok,
|
||||
|
||||
Reference in New Issue
Block a user