This is a helper function for handleClientsBlockedOnKeys(). Its work * is to serve a specific client (receiver) that is blocked on 'key' * in the context of the specified 'db', doing the following: * * 1) Provide the client with the 'value' element. * 2) If the dstkey is not NULL (we are serving a BLMOVE) also push the * 'value' element on the destination list (the "push" side of the comm
| 878 | * BLMOVE that fails to push the value to the destination key as it is |
| 879 | * of the wrong type. */ |
| 880 | int serveClientBlockedOnList(client *receiver, robj *key, robj *dstkey, redisDb *db, robj *value, int wherefrom, int whereto) |
| 881 | { |
| 882 | robj *argv[5]; |
| 883 | std::unique_lock<fastlock> ul(receiver->lock); |
| 884 | |
| 885 | if (dstkey == NULL) { |
| 886 | /* Propagate the [LR]POP operation. */ |
| 887 | argv[0] = (wherefrom == LIST_HEAD) ? shared.lpop : |
| 888 | shared.rpop; |
| 889 | argv[1] = key; |
| 890 | propagate((wherefrom == LIST_HEAD) ? |
| 891 | cserver.lpopCommand : cserver.rpopCommand, |
| 892 | db->id,argv,2,PROPAGATE_AOF|PROPAGATE_REPL); |
| 893 | |
| 894 | /* BRPOP/BLPOP */ |
| 895 | addReplyArrayLen(receiver,2); |
| 896 | addReplyBulk(receiver,key); |
| 897 | addReplyBulk(receiver,value); |
| 898 | |
| 899 | /* Notify event. */ |
| 900 | const char *event = (wherefrom == LIST_HEAD) ? "lpop" : "rpop"; |
| 901 | notifyKeyspaceEvent(NOTIFY_LIST,event,key,receiver->db->id); |
| 902 | } else { |
| 903 | /* BLMOVE */ |
| 904 | robj *dstobj = |
| 905 | lookupKeyWrite(receiver->db,dstkey); |
| 906 | if (!(dstobj && |
| 907 | checkType(receiver,dstobj,OBJ_LIST))) |
| 908 | { |
| 909 | lmoveHandlePush(receiver,dstkey,dstobj,value,whereto); |
| 910 | /* Propagate the LMOVE/RPOPLPUSH operation. */ |
| 911 | int isbrpoplpush = (receiver->lastcmd->proc == brpoplpushCommand); |
| 912 | argv[0] = isbrpoplpush ? shared.rpoplpush : shared.lmove; |
| 913 | argv[1] = key; |
| 914 | argv[2] = dstkey; |
| 915 | argv[3] = getStringObjectFromListPosition(wherefrom); |
| 916 | argv[4] = getStringObjectFromListPosition(whereto); |
| 917 | propagate(isbrpoplpush ? cserver.rpoplpushCommand : cserver.lmoveCommand, |
| 918 | db->id,argv,(isbrpoplpush ? 3 : 5), |
| 919 | PROPAGATE_AOF| |
| 920 | PROPAGATE_REPL); |
| 921 | |
| 922 | /* Notify event ("lpush" or "rpush" was notified by lmoveHandlePush). */ |
| 923 | notifyKeyspaceEvent(NOTIFY_LIST,wherefrom == LIST_TAIL ? "rpop" : "lpop", |
| 924 | key,receiver->db->id); |
| 925 | } else { |
| 926 | /* BLMOVE failed because of wrong |
| 927 | * destination type. */ |
| 928 | return C_ERR; |
| 929 | } |
| 930 | } |
| 931 | return C_OK; |
| 932 | } |
| 933 | |
| 934 | /* Blocking RPOP/LPOP */ |
| 935 | void blockingPopGenericCommand(client *c, int where) { |
no test coverage detected