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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions