node-redis-pubsub icon indicating copy to clipboard operation
node-redis-pubsub copied to clipboard

pub/sub upon update of key/value pair

Open ORESoftware opened this issue 9 years ago • 23 comments

my goal is to use Redis pub/sub (hopefully using this library) to send messages upon an update or insert of a Redis key.

Does this library go low-level enough for that? How can I invoke an nrp.emit upon a Redis key/value update?

Is the best way to do this using keyspace notifications?

http://redis.io/topics/notifications

Please let me know, thanks

ORESoftware avatar Apr 21 '15 23:04 ORESoftware

Currently, this library only handles pub/sub and nothing more. Though it shouldn't be too hard to build a wrapper over it that does what you want.

You can access the raw Redis connection object with nrp.emitter. You could then potentially wrap over the get/set/etc functions in the emitter in order to have them do a nrp.emit call on whatever key is being modified.

This would need to be a separate library as it is outside the scope of this one.

RangerMauve avatar Apr 21 '15 23:04 RangerMauve

thanks, sounds like this library could easily do this. if you do add this functionality, it would be great to have a quick example, something along the lines of:

nrp.on('DEL key:74iegeag2', function (data) { console.log('Hello ' + data.name); });

I guess the emitting part would be taken care of by Redis itself, but a simple example of a handler with the right syntax would be good. Does this make sense?

ORESoftware avatar Apr 21 '15 23:04 ORESoftware

Again, that functionality is something that'd be best left to a library that build on top of this one. The docs on the Redis API can be found here

A starting point might look like:

function make_wrapper(config){
  var nrp = new NRP(config);
  return {
     nrp: nrp,
     get: function(key, cb){
        return nrp.emitter.get(key, cb);
     },
     set: function(key, value, cb){
       nrp.emitter.set(key, value, function(err, result){
         if(err) return cb(err, result);
         nrp.emit("SET "+key, value);
         cb(err, result);
       })
     }
  }
}

RangerMauve avatar Apr 21 '15 23:04 RangerMauve

with all due respect, don't you think it's better to not wrap wrappers? It seems it would be best for me to fork this repo and fix the internals than to wrap a wrapper, no?

ORESoftware avatar Apr 21 '15 23:04 ORESoftware

this repo should ideally be doing the lower level listening to DELs, SETs, etc. Wrapping this library in order to do that is just going to create confusion, IMO

ORESoftware avatar Apr 21 '15 23:04 ORESoftware

When people think "redis pub sub", I doubt they expect much more than pub/sub functionality. And wrapping a wrapper is totally fine since that's how you use modules to create new modules.

If you want I can create this wrapper for you, but it would be more maintainable to keep functionality separated.

RangerMauve avatar Apr 21 '15 23:04 RangerMauve

It would be super awesome if you could create that, I am personally looking to listen to events such as these

http://redis.io/topics/notifications

DEL generates a del event for every deleted key. SET and all its variants (SETEX, SETNX,GETSET) generate set events. However SETEX will also generate an expire events. ... etc

please LMK what you think, thanks

ORESoftware avatar Apr 22 '15 00:04 ORESoftware

Created redis-update-events, please open an issue there with the minimal number of events you were thinking of.

RangerMauve avatar Apr 22 '15 00:04 RangerMauve

cool, thanks RM...can you reconcile this redis-update-events library with this answer here http://stackoverflow.com/questions/29785346/redis-client-to-listen-to-set-and-del-events/29785902#29785902

do you really think they should be separate libs?

ORESoftware avatar Apr 22 '15 16:04 ORESoftware

Yeah, since this would be events specific to operations rather than general pub/sub. I actually think I might not even use node-redis-pubsub for the other library since if you're only listening on events published by Redis itself, then you don't need to have a publish socket.

RangerMauve avatar Apr 22 '15 23:04 RangerMauve

huh

ORESoftware avatar Apr 22 '15 23:04 ORESoftware

The feature in Redis that you were referencing enables the Redis server to publish events whenever certain events occur. That means that you don't have to publish the code yourself. When you use Redis pub/sub, you normally need to create two connections to the server since once you start subscribing on one, you can no longer publish on it. What I'm saying is that since the server is the one publishing events, using node-redis-pubsub wouldn't make sense since it handles publishing and subscribing. A more efficient strategy would be to have a library that only does subscribing to the specific keyspace notifications and leave the publishing the the server whenever you modify something with a different redis connection. Does that make sense?

RangerMauve avatar Apr 22 '15 23:04 RangerMauve

Err, you know what. I think I'm just over-complicating things.

You can definitely just use keyspace notifications without extra hassle.

When you're about to start use this to make sure they're enabled on the server.

var client = nrp.getRedisClient();
client.config("SET","notify-keyspace-events", "KEA");

Then, if you want to listen for when a key foo expires, and emit an event you can use this:

nrp.on("__keyspace@0__:foo expired", function(){
  nrp.emit("foo expired", {});
});
nrp.on("foo expired",function(){
  console.log("Foo must have expired somehow");
});

RangerMauve avatar Apr 23 '15 00:04 RangerMauve

Yes, I agree, I believe you have seen the light. From the start I thought the keyspace stuff belonged with the pub/sub stuff. I think the other library you created for events should be combined with this module and that would be to great effect. Putting them together is a better idea than making them separate.

ORESoftware avatar Apr 23 '15 18:04 ORESoftware

RM - it's a been awhile, but I think Redis PubSub is just a special case of Redis Keyspace Notifs, not the other way around. Does that ring true with you? I hope you agree. If that is indeed true, your PubSub library really needs to subsume keyspace notifs to be the real deal. the fully monty if you will.

ORESoftware avatar May 15 '15 22:05 ORESoftware

Node-redis-pubsub is nothing without subcribing to the KEA

ORESoftware avatar May 15 '15 22:05 ORESoftware

Well, it already supports them out of the box. You'd just need to listen on the keyspace event. Do you think there should be a shortcut or something?

RangerMauve avatar May 15 '15 22:05 RangerMauve

IMO there needs to be clear instructions in the documentation on how to use keyspace notifications with this library. this I believe was my my only complaint with your lib from day one. you have the chance to make it easier than Redis does out of the box.

ORESoftware avatar May 15 '15 22:05 ORESoftware

Sure. I'll see what I can do with the docs. Maybe add a onKeyspace(key, event,fn) event to make it nicer too.

RangerMauve avatar May 15 '15 22:05 RangerMauve

You need to let people know that keyspace notifs need to be enabled by calling

redis-cli config set notify-keyspace-events KEA

or editing the redis.conf file directly and putting in a line with:

notify-keyspace-events KEA

it could take people hours to figure that out

keyspace notifs might not be that important, but you might as well demonstrate an example.

all it takes is setting KEA and then something like:

client.subscribe('__keyspace@0__:set'); client.subscribe('__keyspace@0__:del');

etc

maybe even add a note about different databases, instead of just DB 0

ORESoftware avatar May 15 '15 22:05 ORESoftware

yes I agree, you should sugarize the syntax since __keyspace@0__: is just weird

ORESoftware avatar May 15 '15 22:05 ORESoftware

Maybe add something to the config for enabling it? Or maybe it'd be even easier to auto enable it the first time the shortcut gets called.

RangerMauve avatar May 15 '15 22:05 RangerMauve

yeah you can add it to redis.conf with

notify-keyspace-events KEA

ORESoftware avatar May 15 '15 22:05 ORESoftware