nodejs
nodejs copied to clipboard
Set fetch keepalive
Support reference number
Description
I would like to set the HTTP agent keepalive to speed up the HTTP call to the CT APIs:
https://github.com/node-fetch/node-fetch#custom-agent
Current code:
const commercetoolsClient = new ClientBuilder()
.withProjectKey(config.commercetools.auth.projectKey)
.withHttpMiddleware({
host: config.commercetools.host,
fetch
})
.withUserAgentMiddleware()
.build()
const apiRoot = createApiBuilderFromCtpClient(commercetoolsClient)
Expected Behavior
Current Behavior
All works, but the customers import is slow
Context
I need to import >500k rows
Possible Solution
- Parallelize calls (done)
- Set the HTTP agent to keep alive the connection: should be supported by this SDK
example:
.withHttpMiddleware({
host: config.commercetools.host,
fetch,
fetchOptions: {
agent: new https.Agent({ keepAlive: true })
}
})
@Eomm we're looking into the issue, and came up with a work around that might be worth trying.
If you're in a nodejs runtime, there is a globalAgent you can adjust keepAlive settings on. I'm kind of an old school nodejs user myself so please excuse all the require.
let http = require('http')
http.globalAgent.keepAlive = true
//instantiate your middleware client afterwards.
Note, I have not actually validated that this works for nodejs, but is something I'm fairly confident should work. Though it will set all HTTP requests using the globalAgent to share connections.
I think actually the best way to set specific fetch related options is to make a facade fetcher:
function fetcher(resource, options) {
return fetch(resource, Object.assign(options, { "keepAlive": true })
}
...
.withHttpMiddleware({
host: config.commercetools.host,
fetch: fetcher
})
@Eomm let me know if that suits you better. And remember to close the issue if you're satisfied!
You will need to use node http agent to send kee-alive requests (to check if you traffic uses keep-alive use NODE_DEBUG=http):
import nodeFetch from "node-fetch";
import http from "http";
import https from "https";
const httpAgent = new http.Agent({ keepAlive: true });
const httpsAgent = new https.Agent({ keepAlive: true });
const agent = (parsedURL: URL) => {
return parsedURL.protocol == "http:" ? httpAgent : httpsAgent;
};
const wrappedFetch = async (url: RequestInfo, options: RequestInit) => {
log().debug(`Fetching with node-fetch == url: ${JSON.stringify(url)}, ${JSON.stringify(options)}`);
return nodeFetch(url as any, Object.assign({}, options, { agent } as any));
};
const options: HttpMiddlewareOptions = {
host: host,
enableRetry: true,
fetch: wrappedFetch as unknown as typeof fetch,
};
....
.withHttpMiddleware(options)