Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RedisClient isolationPool becomes unusable after disconnect() #2406

Closed
postpersonality opened this issue Feb 9, 2023 · 0 comments · Fixed by #2409
Closed

RedisClient isolationPool becomes unusable after disconnect() #2406

postpersonality opened this issue Feb 9, 2023 · 0 comments · Fixed by #2409
Labels

Comments

@postpersonality
Copy link

postpersonality commented Feb 9, 2023

Description

Example code https://github.com/redis/node-redis/blob/master/examples/transaction-with-watch.js does not work if instead of

const client = createClient();
await client.connect();

we do

const client = createClient();
await client.connect();
await client.disconnect(); // After that any client.executeIsolated() is impossible
await client.connect();

The code fails with Error: pool is draining and cannot accept work error.

Full source code of the modified `transaction-with-watch.js`

import { createClient, WatchError } from 'redis';

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const client = createClient();
const client = createClient();
await client.connect();
await client.disconnect(); // After that any client.executeIsolated() is impossible
await client.connect();

function restrictFunctionCalls(fn, maxCalls) {
  let count = 1;
  return function (...args) {
    return count++ < maxCalls ? fn(...args) : false;
  };
}

const fn = restrictFunctionCalls(transaction, 4);

async function transaction() {
  try {
    await client.executeIsolated(async (isolatedClient) => {
      await isolatedClient.watch('paymentId:1259');
      const multi = isolatedClient
        .multi()
        .set('paymentId:1259', 'Payment Successfully Completed!')
        .set('paymentId:1260', 'Refund Processed Successfully!');
      await delay(5000); // Do some changes to the watched key during this time...
      await multi.exec();
      console.log('Transaction completed Successfully!');
      client.quit();
    });
  } catch (error) {
    if (error instanceof WatchError) {
      console.log('Transaction Failed Due To Concurrent Modification!');
      fn();
    } else {
      console.log(`Error: ${error}`);
      client.quit();
    }
  }
}

transaction();

Node.js Version

v16.17.1

Redis Server Version

6.2.7

Node Redis Version

4.6.4

Platform

Linux

Logs

No response

leibale added a commit to leibale/node-redis that referenced this issue Feb 13, 2023
@leibale leibale added this to In progress in v4.6.5 Feb 23, 2023
@leibale leibale removed this from In progress in v4.6.5 Feb 23, 2023
leibale added a commit that referenced this issue Apr 26, 2023
* fix #2406 - fix isolationPool after reconnect

* revert breaking change

* fix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant