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

Function serveClientsBlockedOnListKey

src/blocked.cpp:287–345  ·  view source on GitHub ↗

Helper function for handleClientsBlockedOnKeys(). This function is called * when there may be clients blocked on a list key, and there may be new * data to fetch (the key is ready). */

Source from the content-addressed store, hash-verified

285 * when there may be clients blocked on a list key, and there may be new
286 * data to fetch (the key is ready). */
287void serveClientsBlockedOnListKey(robj *o, readyList *rl) {
288 /* We serve clients in the same order they blocked for
289 * this key, from the first blocked to the last. */
290 dictEntry *de = dictFind(rl->db->blocking_keys,rl->key);
291 if (de) {
292 list *clients = (list*)dictGetVal(de);
293 int numclients = listLength(clients);
294
295 while(numclients--) {
296 listNode *clientnode = listFirst(clients);
297 client *receiver = (client*)clientnode->value;
298 std::unique_lock<decltype(receiver->lock)> lock(receiver->lock);
299
300 if (receiver->btype != BLOCKED_LIST) {
301 /* Put at the tail, so that at the next call
302 * we'll not run into it again. */
303 listRotateHeadToTail(clients);
304 continue;
305 }
306
307 robj *dstkey = receiver->bpop.target;
308 int wherefrom = receiver->bpop.listpos.wherefrom;
309 int whereto = receiver->bpop.listpos.whereto;
310 robj *value = listTypePop(o, wherefrom);
311
312 if (value) {
313 /* Protect receiver->bpop.target, that will be
314 * freed by the next unblockClient()
315 * call. */
316 if (dstkey) incrRefCount(dstkey);
317
318 monotime replyTimer;
319 elapsedStart(&replyTimer);
320 if (serveClientBlockedOnList(receiver,
321 rl->key,dstkey,rl->db,value,
322 wherefrom, whereto) == C_ERR)
323 {
324 /* If we failed serving the client we need
325 * to also undo the POP operation. */
326 listTypePush(o,value,wherefrom);
327 }
328 updateStatsOnUnblock(receiver, 0, elapsedUs(replyTimer));
329 unblockClient(receiver);
330
331 if (dstkey) decrRefCount(dstkey);
332 decrRefCount(value);
333 } else {
334 break;
335 }
336 }
337 }
338
339 if (listTypeLength(o) == 0) {
340 dbDelete(rl->db,rl->key);
341 notifyKeyspaceEvent(NOTIFY_GENERIC,"del",rl->key,rl->db->id);
342 }
343 /* We don't call signalModifiedKey() as it was already called
344 * when an element was pushed on the list. */

Callers 1

Calls 14

listRotateHeadToTailFunction · 0.85
listTypePopFunction · 0.85
incrRefCountFunction · 0.85
elapsedStartFunction · 0.85
serveClientBlockedOnListFunction · 0.85
listTypePushFunction · 0.85
updateStatsOnUnblockFunction · 0.85
elapsedUsFunction · 0.85
unblockClientFunction · 0.85
decrRefCountFunction · 0.85
listTypeLengthFunction · 0.85
dbDeleteFunction · 0.85

Tested by

no test coverage detected