MCPcopy Create free account
hub / github.com/F-Stack/f-stack / xackCommand

Function xackCommand

app/redis-6.2.6/src/t_stream.c:2543–2590  ·  view source on GitHub ↗

XACK ... * * Acknowledge a message as processed. In practical terms we just check the * pendine entries list (PEL) of the group, and delete the PEL entry both from * the group and the consumer (pending messages are referenced in both places). * * Return value of the command is the number of messages successfully * acknowledged, that is, the IDs we were actually

Source from the content-addressed store, hash-verified

2541 * acknowledged, that is, the IDs we were actually able to resolve in the PEL.
2542 */
2543void xackCommand(client *c) {
2544 streamCG *group = NULL;
2545 robj *o = lookupKeyRead(c->db,c->argv[1]);
2546 if (o) {
2547 if (checkType(c,o,OBJ_STREAM)) return; /* Type error. */
2548 group = streamLookupCG(o->ptr,c->argv[2]->ptr);
2549 }
2550
2551 /* No key or group? Nothing to ack. */
2552 if (o == NULL || group == NULL) {
2553 addReply(c,shared.czero);
2554 return;
2555 }
2556
2557 /* Start parsing the IDs, so that we abort ASAP if there is a syntax
2558 * error: the return value of this command cannot be an error in case
2559 * the client successfully acknowledged some messages, so it should be
2560 * executed in a "all or nothing" fashion. */
2561 streamID static_ids[STREAMID_STATIC_VECTOR_LEN];
2562 streamID *ids = static_ids;
2563 int id_count = c->argc-3;
2564 if (id_count > STREAMID_STATIC_VECTOR_LEN)
2565 ids = zmalloc(sizeof(streamID)*id_count);
2566 for (int j = 3; j < c->argc; j++) {
2567 if (streamParseStrictIDOrReply(c,c->argv[j],&ids[j-3],0) != C_OK) goto cleanup;
2568 }
2569
2570 int acknowledged = 0;
2571 for (int j = 3; j < c->argc; j++) {
2572 unsigned char buf[sizeof(streamID)];
2573 streamEncodeID(buf,&ids[j-3]);
2574
2575 /* Lookup the ID in the group PEL: it will have a reference to the
2576 * NACK structure that will have a reference to the consumer, so that
2577 * we are able to remove the entry from both PELs. */
2578 streamNACK *nack = raxFind(group->pel,buf,sizeof(buf));
2579 if (nack != raxNotFound) {
2580 raxRemove(group->pel,buf,sizeof(buf),NULL);
2581 raxRemove(nack->consumer->pel,buf,sizeof(buf),NULL);
2582 streamFreeNACK(nack);
2583 acknowledged++;
2584 server.dirty++;
2585 }
2586 }
2587 addReplyLongLong(c,acknowledged);
2588cleanup:
2589 if (ids != static_ids) zfree(ids);
2590}
2591
2592/* XPENDING <key> <group> [[IDLE <idle>] <start> <stop> <count> [<consumer>]]
2593 *

Callers

nothing calls this directly

Calls 12

lookupKeyReadFunction · 0.85
checkTypeFunction · 0.85
streamLookupCGFunction · 0.85
addReplyFunction · 0.85
zmallocFunction · 0.85
streamEncodeIDFunction · 0.85
raxFindFunction · 0.85
raxRemoveFunction · 0.85
streamFreeNACKFunction · 0.85
addReplyLongLongFunction · 0.85
zfreeFunction · 0.70

Tested by

no test coverage detected