Jed
Jed

Reputation: 512

node-redis: How does executeIsolated impact watched keys?

I'm trying to debug some WatchErrors in my project and am noticing that we aren't using an isolatedClient and am wondering if that is the cause. I don't see any logs (or code paths) that would indicate that the watched keys are being changed after being watched.

Here is basically what my code looks like when I actually write to Redis in a transaction:

try {
  await this.client.watch(key);
  await this.client
    .multi()
    .hSet(key, some_value)
    .expire(key, some_expiration)
    .exec();
}
catch (e) {
  if (e instanceof WatchError) {
    // seeing this block get hit often
  }

  throw e;
}

I noticed in the node-redis README that the Transactions section gives an example without calling .watch() without creating an isolatedClient. However, in the linked example that does call .watch(), there is the additional creation of an isolatedClient with the executeIsolated method.

What exactly are the implications of using an isolatedClient? Do we need to use one of these if we are calling .watch() and if so, why? Will a WatchError be thrown if a different connection is used between .watch() and .exec()?

Upvotes: 0

Views: 343

Answers (1)

Leibale Eidelman
Leibale Eidelman

Reputation: 3194

redis-server stores the WATCH state on the connection, which means that concurrent WATCH and MULTI/EXEC will override the state for each other... in this scenario you'll need to have a pool of connections, and every time you need to WATCH, take a connection from the pool, and use it instead (which is exactly what executeIsolated is doing):

client.executeIsolated(async isolatedClient => {
  await isolatedClient.watch(key);
  await isolatedClient
    .multi()
    .hSet(key, some_value)
    .expire(key, some_expiration)
    .exec();
});

you can configure the pool behavior by passing the isolationPoolOptions option to createClient:

createClient({
  isolationPoolOptions: {
    min: 1,
    max: 100
  }
});

see generic-pool for more options.

Upvotes: 1

Related Questions