MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / xackCommand

Function xackCommand

src/t_stream.cpp:2545–2593  ·  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

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

Callers

nothing calls this directly

Calls 14

lookupKeyReadFunction · 0.85
checkTypeFunction · 0.85
streamLookupCGFunction · 0.85
ptrFromObjFunction · 0.85
szFromObjFunction · 0.85
addReplyFunction · 0.85
zmallocFunction · 0.85
streamEncodeIDFunction · 0.85
raxFindFunction · 0.85
raxRemoveFunction · 0.85
streamFreeNACKFunction · 0.85

Tested by

no test coverage detected