valkey-io / iovalkey

MIT License
85 stars 7 forks source link

Build Sharded PubSub command routing based on channel/slot ownership #13

Open hpatro opened 1 week ago

hpatro commented 1 week ago

Copied from: https://github.com/redis/ioredis/issues/1759

Hi! It seems there is an issue with the spublish()/ssubscribe() methods added in 6285e80:

 import { Cluster } from "ioredis";

 const clusterNodes = [
   {
     host: "localhost",
     port: 7000,
   },
   {
     host: "localhost",
     port: 7001,
   },
   {
     host: "localhost",
     port: 7002,
   },
   {
     host: "localhost",
     port: 7003,
   },
   {
     host: "localhost",
     port: 7004,
   },
   {
     host: "localhost",
     port: 7005,
   },
 ];

 const pubClient = new Cluster(clusterNodes);
 const subClient = pubClient.duplicate();

 subClient.ssubscribe("foo", () => {
   pubClient.spublish("foo", "bar");
 });

 subClient.on("smessage", (_, message) => {
   console.log("got", message); // never received
 });

The smessage event is not received. It works with classic publish()/subscribe() though:

 subClient.subscribe("foo", () => {
   pubClient.publish("foo", "bar");
 });

 subClient.on("message", (_, message) => {
   console.log("got", message); // prints "got bar"
 });

My docker-compose.yml, for reproducibility:

 services:
   redis-cluster:
     image: grokzen/redis-cluster:7.0.10
     ports:
       - "7000-7005:7000-7005"

The test case here looks a bit weird, shouldn't it be something like:

 const pub = new Cluster(options);
 const ssub = new Cluster(options);

 ssub.ssubscribe("test cluster", function () {
   pub.spublish("test shard channel", "hi");

   // node1.write(node1.findClientByName("ioredis-cluster(subscriber)"), [
   //   "smessage",
   //   "test shard channel",
   //   "hi",
   // ]);
 });

Thanks in advance!


I think this hurts the adoption of iovalkey and user(s) seems to settle on other alternatives due to missing support.

mcollina commented 5 days ago

This is a good feature to add! Would you like to send a PR?