Permalink
Browse files

Implemented CHANNELS command per issue #221 to list server publish/su…

…bscribe channels
  • Loading branch information...
1 parent 4ca7492 commit 52dbc6335a4346e711d8a69aa62605d112e5b6ec @fritzy committed Mar 29, 2012
Showing with 47 additions and 1 deletion.
  1. +28 −0 src/pubsub.c
  2. +1 −0 src/redis.c
  3. +1 −0 src/redis.h
  4. +17 −1 tests/unit/pubsub.tcl
View
@@ -48,6 +48,34 @@ int pubsubSubscribeChannel(redisClient *c, robj *channel) {
return retval;
}
+/* Debug command to return the full list of server channels.
+ * Not for use in production as command will not be performant with a large
+ * number of channels. */
+void channelsCommand(redisClient *c) {
+ dictIterator *di;
+ dictEntry *de;
+ sds pattern = c->argv[1]->ptr;
+ int plen = sdslen(pattern), allchans;
+ unsigned long numchans = 0;
+ void *replylen = addDeferredMultiBulkLength(c);
+
+ di = dictGetIterator(server.pubsub_channels);
+ allchans = (pattern[0] == '*' && pattern[1] == '\0');
+ while((de = dictNext(di)) != NULL) {
+ robj *chanobj = dictGetKey(de);
+ incrRefCount(chanobj);
+ sds chan = (sds)chanobj->ptr;
+
+ if (allchans || stringmatchlen(pattern,plen,chan,sdslen(chan),0)) {
+ addReplyBulk(c,chanobj);
+ numchans++;
+ }
+ decrRefCount(chanobj);
+ }
+ dictReleaseIterator(di);
+ setDeferredMultiBulkLength(c,replylen,numchans);
+}
+
/* Unsubscribe a client from a channel. Returns 1 if the operation succeeded, or
* 0 if the client was not subscribed to the specified channel. */
int pubsubUnsubscribeChannel(redisClient *c, robj *channel, int notify) {
View
@@ -230,6 +230,7 @@ struct redisCommand redisCommandTable[] = {
{"psubscribe",psubscribeCommand,-2,"rps",0,NULL,0,0,0,0,0},
{"punsubscribe",punsubscribeCommand,-1,"rps",0,NULL,0,0,0,0,0},
{"publish",publishCommand,3,"pf",0,NULL,0,0,0,0,0},
+ {"channels",channelsCommand,2,"rpRS",0,NULL,1,1,1,0,0},
{"watch",watchCommand,-2,"rs",0,noPreloadGetKeys,1,-1,1,0,0},
{"unwatch",unwatchCommand,1,"rs",0,NULL,0,0,0,0,0},
{"cluster",clusterCommand,-2,"ar",0,NULL,0,0,0,0,0},
View
@@ -1228,6 +1228,7 @@ void unsubscribeCommand(redisClient *c);
void psubscribeCommand(redisClient *c);
void punsubscribeCommand(redisClient *c);
void publishCommand(redisClient *c);
+void channelsCommand(redisClient *c);
void watchCommand(redisClient *c);
void unwatchCommand(redisClient *c);
void clusterCommand(redisClient *c);
View
@@ -99,6 +99,22 @@ start_server {tags {"pubsub"}} {
$rd1 close
}
+ test "PUBLISH/SUBSCRIBE command CHANNELS returns all subscriptions" {
+ set rd1 [redis_deferring_client]
+ set rd2 [redis_deferring_client]
+ subscribe $rd1 {chan1}
+ subscribe $rd2 {chan1}
+ subscribe $rd1 {chan2}
+ subscribe $rd1 {chan3}
+ unsubscribe $rd1 {chan2}
+ subscribe $rd2 {chan4}
+ assert_equal {chan1 chan3 chan4} [lsort [r channels *]]
+
+ # clean up clients
+ $rd1 close
+ $rd2 close
+ }
+
test "SUBSCRIBE to one channel more than once" {
set rd1 [redis_deferring_client]
assert_equal {1 1 1} [subscribe $rd1 {chan1 chan1 chan1}]
@@ -192,4 +208,4 @@ start_server {tags {"pubsub"}} {
# clean up clients
$rd1 close
}
-}
+}

0 comments on commit 52dbc63

Please sign in to comment.