FG
๐Ÿ—„๏ธ Databases

"Connection is closed" during quit() when commandQueue has entries

Freshabout 21 hours ago
Mar 14, 20260 views
Confidence Score50%
50%

Problem

Problem `await ioredis.quit()` throws an `Error` when there are still items on the `commandQueue`. [code block] Version ioredis 5.8.0 Context We have code for a health check that connects and immediately disconnects using `await ioredis.quit()`. The issue occurs often since https://github.com/redis/ioredis/pull/2011. I assume the reason for this is, that we now have entries on the `commandQueue` immediately. Workaround The issue does not occur anymore when I set `disableClientInfo` to `true`. Reason Usually the `commandQueue` is empty and the connection terminates sucessfully. However, when the error occures, we have the following entries on the `commandQueue` [code block] The `closeHandler` flushes the queue with an error (https://github.com/redis/ioredis/blob/8dad79f9d05c8891d0c70336f484b065b9865ae2/lib/redis/event_handler.ts#L227). Thus, `quit` can only ever complete successfully if the queue is empty.

Error Output

Error: Connection is closed.

Unverified for your environment

Select your OS to check compatibility.

1 Fix

Canonical Fix
Unverified Fix
New Fix โ€“ Awaiting Verification

Implement Command Queue Check Before Quit

Medium Risk

The error occurs because the `quit()` method in ioredis attempts to close the connection while there are still commands in the `commandQueue`. This leads to an error as the connection cannot be closed until all queued commands are processed. The change in behavior was introduced in a previous update that altered how command queuing is handled.

Awaiting Verification

Be the first to verify this fix

  1. 1

    Check Command Queue Before Quitting

    Before calling `await ioredis.quit()`, check if the `commandQueue` is empty. If it is not empty, wait for the commands to finish processing.

    typescript
    if (ioredis.commandQueue.length > 0) { await ioredis.commandQueue[0].promise; } await ioredis.quit();
  2. 2

    Implement Retry Logic

    If the command queue is not empty, implement a retry mechanism that waits for a short duration before checking the queue again. This ensures that the quit operation is retried until the queue is empty.

    typescript
    async function safeQuit(redis) { while (redis.commandQueue.length > 0) { await new Promise(resolve => setTimeout(resolve, 100)); } await redis.quit(); }
  3. 3

    Set disableClientInfo to True

    As a temporary workaround, set the `disableClientInfo` option to true when creating the Redis client to avoid the issue until a permanent solution is implemented.

    typescript
    const ioredis = new Redis({ disableClientInfo: true });
  4. 4

    Update Documentation

    Update the project documentation to inform developers about the need to check the command queue before quitting and the implications of using `disableClientInfo`.

Validation

To confirm the fix worked, run the health check multiple times and ensure that no 'Connection is closed' errors are thrown during the quit process. Additionally, monitor the command queue to verify it is empty before quitting.

Sign in to verify this fix

Environment

Submitted by

AC

Alex Chen

2450 rep

Tags

redisiorediscachebug