XINFO CONSUMERS * XINFO GROUPS * XINFO STREAM [FULL [COUNT ]] * XINFO HELP. */
| 3481 | * XINFO STREAM <key> [FULL [COUNT <count>]] |
| 3482 | * XINFO HELP. */ |
| 3483 | void xinfoCommand(client *c) { |
| 3484 | stream *s = NULL; |
| 3485 | char *opt; |
| 3486 | robj *key; |
| 3487 | |
| 3488 | /* HELP is special. Handle it ASAP. */ |
| 3489 | if (!strcasecmp(c->argv[1]->ptr,"HELP")) { |
| 3490 | const char *help[] = { |
| 3491 | "CONSUMERS <key> <groupname>", |
| 3492 | " Show consumers of <groupname>.", |
| 3493 | "GROUPS <key>", |
| 3494 | " Show the stream consumer groups.", |
| 3495 | "STREAM <key> [FULL [COUNT <count>]", |
| 3496 | " Show information about the stream.", |
| 3497 | NULL |
| 3498 | }; |
| 3499 | addReplyHelp(c, help); |
| 3500 | return; |
| 3501 | } else if (c->argc < 3) { |
| 3502 | addReplySubcommandSyntaxError(c); |
| 3503 | return; |
| 3504 | } |
| 3505 | |
| 3506 | /* With the exception of HELP handled before any other sub commands, all |
| 3507 | * the ones are in the form of "<subcommand> <key>". */ |
| 3508 | opt = c->argv[1]->ptr; |
| 3509 | key = c->argv[2]; |
| 3510 | |
| 3511 | /* Lookup the key now, this is common for all the subcommands but HELP. */ |
| 3512 | robj *o = lookupKeyReadOrReply(c,key,shared.nokeyerr); |
| 3513 | if (o == NULL || checkType(c,o,OBJ_STREAM)) return; |
| 3514 | s = o->ptr; |
| 3515 | |
| 3516 | /* Dispatch the different subcommands. */ |
| 3517 | if (!strcasecmp(opt,"CONSUMERS") && c->argc == 4) { |
| 3518 | /* XINFO CONSUMERS <key> <group>. */ |
| 3519 | streamCG *cg = streamLookupCG(s,c->argv[3]->ptr); |
| 3520 | if (cg == NULL) { |
| 3521 | addReplyErrorFormat(c, "-NOGROUP No such consumer group '%s' " |
| 3522 | "for key name '%s'", |
| 3523 | (char*)c->argv[3]->ptr, (char*)key->ptr); |
| 3524 | return; |
| 3525 | } |
| 3526 | |
| 3527 | addReplyArrayLen(c,raxSize(cg->consumers)); |
| 3528 | raxIterator ri; |
| 3529 | raxStart(&ri,cg->consumers); |
| 3530 | raxSeek(&ri,"^",NULL,0); |
| 3531 | mstime_t now = mstime(); |
| 3532 | while(raxNext(&ri)) { |
| 3533 | streamConsumer *consumer = ri.data; |
| 3534 | mstime_t idle = now - consumer->seen_time; |
| 3535 | if (idle < 0) idle = 0; |
| 3536 | |
| 3537 | addReplyMapLen(c,3); |
| 3538 | addReplyBulkCString(c,"name"); |
| 3539 | addReplyBulkCBuffer(c,consumer->name,sdslen(consumer->name)); |
| 3540 | addReplyBulkCString(c,"pending"); |
nothing calls this directly
no test coverage detected