XCLAIM * [IDLE ] [TIME ] [RETRYCOUNT ] * [FORCE] [JUSTID] * * Gets ownership of one or multiple messages in the Pending Entries List * of a given stream consumer group. * * If the message ID (among the specified ones) exists, and its idle * time greater or equal to , then the me
| 2846 | * successfully claimed, so that the caller is able to understand |
| 2847 | * what messages it is now in charge of. */ |
| 2848 | void xclaimCommand(client *c) { |
| 2849 | streamCG *group = NULL; |
| 2850 | robj_roptr o = lookupKeyRead(c->db,c->argv[1]); |
| 2851 | long long minidle; /* Minimum idle time argument. */ |
| 2852 | long long retrycount = -1; /* -1 means RETRYCOUNT option not given. */ |
| 2853 | mstime_t deliverytime = -1; /* -1 means IDLE/TIME options not given. */ |
| 2854 | int force = 0; |
| 2855 | int justid = 0; |
| 2856 | streamID static_ids[STREAMID_STATIC_VECTOR_LEN]; |
| 2857 | streamID *ids = static_ids; |
| 2858 | |
| 2859 | if (o) { |
| 2860 | if (checkType(c,o,OBJ_STREAM)) return; /* Type error. */ |
| 2861 | group = streamLookupCG((stream*)ptrFromObj(o),szFromObj(c->argv[2])); |
| 2862 | } |
| 2863 | |
| 2864 | { // BEGIN GOTO PROTECTED VARS |
| 2865 | /* No key or group? Send an error given that the group creation |
| 2866 | * is mandatory. */ |
| 2867 | if (o == nullptr || group == NULL) { |
| 2868 | addReplyErrorFormat(c,"-NOGROUP No such key '%s' or " |
| 2869 | "consumer group '%s'", (char*)ptrFromObj(c->argv[1]), |
| 2870 | (char*)ptrFromObj(c->argv[2])); |
| 2871 | return; |
| 2872 | } |
| 2873 | |
| 2874 | if (getLongLongFromObjectOrReply(c,c->argv[4],&minidle, |
| 2875 | "Invalid min-idle-time argument for XCLAIM") |
| 2876 | != C_OK) return; |
| 2877 | if (minidle < 0) minidle = 0; |
| 2878 | |
| 2879 | /* Start parsing the IDs, so that we abort ASAP if there is a syntax |
| 2880 | * error: the return value of this command cannot be an error in case |
| 2881 | * the client successfully claimed some message, so it should be |
| 2882 | * executed in a "all or nothing" fashion. */ |
| 2883 | int j; |
| 2884 | int id_count = c->argc-5; |
| 2885 | if (id_count > STREAMID_STATIC_VECTOR_LEN) |
| 2886 | ids = (streamID*)zmalloc(sizeof(streamID)*id_count); |
| 2887 | for (j = 5; j < c->argc; j++) { |
| 2888 | if (streamParseStrictIDOrReply(NULL,c->argv[j],&ids[j-5],0) != C_OK) break; |
| 2889 | } |
| 2890 | int last_id_arg = j-1; /* Next time we iterate the IDs we now the range. */ |
| 2891 | |
| 2892 | /* If we stopped because some IDs cannot be parsed, perhaps they |
| 2893 | * are trailing options. */ |
| 2894 | mstime_t now = mstime(); |
| 2895 | streamID last_id = {0,0}; |
| 2896 | int propagate_last_id = 0; |
| 2897 | for (; j < c->argc; j++) { |
| 2898 | int moreargs = (c->argc-1) - j; /* Number of additional arguments. */ |
| 2899 | char *opt = szFromObj(c->argv[j]); |
| 2900 | if (!strcasecmp(opt,"FORCE")) { |
| 2901 | force = 1; |
| 2902 | } else if (!strcasecmp(opt,"JUSTID")) { |
| 2903 | justid = 1; |
| 2904 | } else if (!strcasecmp(opt,"IDLE") && moreargs) { |
| 2905 | j++; |
nothing calls this directly
no test coverage detected