Skip to content

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

@rlindner81

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

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