Skip to content

Provide public API for getting node-specific client for WATCH/MULTI/EXEC in cluster mode #3194

Description

@rlindner81

Problem

When using WATCH with MULTI/EXEC in cluster mode, the cluster client doesn't have a WATCH method because WATCH requires connection-level state on a specific node. The current workaround requires using internal APIs and calculating slots manually:

const calculateSlot = require("cluster-key-slot");

const slot = calculateSlot(key);
const shard = cluster.slots[slot];
const nodeClient = await cluster.nodeClient(shard.master);

await nodeClient.WATCH(key);
// ... GET, calculate new value ...
const multi = nodeClient.MULTI();
multi.addCommand(["SET", key, value]);
await multi.EXEC();

This works but has some issues:

  1. Requires importing cluster-key-slot separately, even though it's already a dependency of @redis/client
  2. The slots array and nodeClient method are somewhat poorly documented

Proposed solution

A convenience method on the cluster client that returns the node client for a given key:

const nodeClient = await cluster.getNodeClientForKey(key);
await nodeClient.WATCH(key);
// ...

Use case

Atomic read-modify-write operations where the calculation happens in application code:

await client.WATCH(key);
const oldValue = await client.GET(key);
const newValue = calculateNewValue(oldValue); // app logic
const multi = client.MULTI();
multi.SET(key, newValue);
await multi.EXEC(); // returns null if key changed, retry

This is a common pattern that currently requires workarounds in cluster mode.

Environment

  • @redis/client version: 5.11.0
  • Node.js version: 22.x

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions