-
-
Notifications
You must be signed in to change notification settings - Fork 969
Closed
Labels
bugSomething does not work as it shouldSomething does not work as it shouldexternalThe issue related to an external projectThe issue related to an external project✭ help wanted ✭
Description
Hello,
We are facing a memory leak in our production environment, using got and it's cache feature (with a KeyvRedis storage backend).
A heap dump revealed that most memory is retained by multiple error event listener on the single KeyvRedis instance.
Further analysis showed that for each request, a new CacheableRequest is instantiated :
if (options.cache) {
const cacheableRequest = new CacheableRequest(fn.request, options.cache);
const cacheRequest = cacheableRequest(options, handleResponse);
cacheRequest.once('error', error => {
if (error instanceof CacheableRequest.RequestError) {
emitError(new RequestError(error, options));
} else {
emitError(new CacheError(error, options));
}
});
cacheRequest.once('request', handleRequest);
}
Then, for each CacheableRequest, a new Keyv is instantiated :
this.cache = new Keyv({
uri: typeof cacheAdapter === 'string' && cacheAdapter,
store: typeof cacheAdapter !== 'string' && cacheAdapter,
namespace: 'cacheable-request'
});
KeyvRedis being an EventEmitter, a eventListener is registered.
if (typeof this.opts.store.on === 'function') {
this.opts.store.on('error', err => this.emit('error', err));
}
The full context of the request being retained by this event listener.
Is there something wrong with the way we use got ? Is there a way to prevent CacheableRequest to be instantiated for each request ?
We tried using got.create, but that didn't work.
Thanks.
Metadata
Metadata
Assignees
Labels
bugSomething does not work as it shouldSomething does not work as it shouldexternalThe issue related to an external projectThe issue related to an external project✭ help wanted ✭