Hello. I can't resolve the issue with my Jest tests because of ioredis. Recently I started recieving messages after Jest finished all tests:
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --runInBand --detectOpenHandles to find leaks.
After a few days of struggling I found the module called leaked-handles, installed it and started debugging. And it seems like both redis.quit() and redis.disconnect() not working and connection remains opened after those calls. The error is:
tcp handle leaked at one of:
at D:\github\umbress\node_modules\ioredis\built\connectors\StandaloneConnector.js:58:45
tcp stream {
fd: -1,
readable: true,
writable: true,
address: { address: '127.0.0.1', family: 'IPv4', port: 59823 },
serverAddr: null
}
I couldn't find any mentioning of ioredis at Jest repo and viceversa. Is there anything that can be done to close connection properly?
Hi, I am experiencing the same behaviour with ioredis and jest
How about performing a redis.quit() or redis.disconnect() inside of your after or afterEach teardown methods?
I'm facing the same issue and had to use jest's --forceExit option, which clearly is not the best solution. It seems that redis.disconnect() should be an async operation so that we could add a callback to be executed after the connection is properly terminated. Currently it just triggers the disconnection but does not wait it to be complete. When jest finishes executing the tests the connection is still open.
I think something like this in after should do the trick:
await new Promise( (reject, resolve) => {
client.once("end", resolve());
client.quite();
})
Having a similar issue where I am calling quit on all ioredis clients in my afterAll hook and it still is leaking events after the tests.
I'm having a similar issue. I was able to work around it by continually checking the connection status. If it's not disconnected, just wait 200ms and check again, etc:
redis.disconnect();
while (redis.status === "connected") {
await new Promise(r => setTimeout(r, 200));
}
+1 with the issue here, had both redis.quit() awaited and redis.disconnect() called but nothing :/
How about performing a redis.quit() or redis.disconnect() inside of your after or afterEach teardown methods?
I've tried both without any success too🤷♂️
I finally got it working, is anybody interested in a sample repo?
I finally got it working, is anybody interested in a sample repo?
I'd love to see a working solution.
I finally got it working, is anybody interested in a sample repo?
Let's compare.
const teardown = async (redis: RedisClient) => {
await new Promise((resolve) => {
redis.quit();
redis.on('end', resolve);
});
};
afterAll(async () => {
await teardown(redis);
});
No need to compare @jaredjj3, you got it right :)
It also work with simply
afterAll(async () => {
await redis.quit()
})
I originally got the issue because I was wrapping it in a Nest.js service but I realized afterwards that I wasn't correctly handling lifecycle like :
import IORedis, * as Redis from 'ioredis'
import { Injectable, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common'
@Injectable()
export class RedisService implements OnApplicationBootstrap, OnApplicationShutdown {
private redis: IORedis.Redis
// ...
async onApplicationBootstrap() {
redis = new Redis()
}
async onApplicationShutdown() {
await redis.quit()
}
}
In the meantime I switched to Nest.js basic implementation which use redis under the hood and for which using promisify also made my life easier.
@jsking216 I made a sample repo with tests for ioredis / redis / Nest.js 👌
Same with the new version 4.19 but with 4.17 all it's ok
Supposed to be fixed in the latest release
Found the same issue in 4.19.2.
Able to remove the error by using:
afterAll(async () => {
await this.redis.quit();
});
Most helpful comment
+1 with the issue here, had both
redis.quit()awaited andredis.disconnect()called but nothing :/