WAIT for N replicas to acknowledge the processing of our latest * write command (and all the previous commands). */
| 3183 | /* WAIT for N replicas to acknowledge the processing of our latest |
| 3184 | * write command (and all the previous commands). */ |
| 3185 | void waitCommand(client *c) { |
| 3186 | mstime_t timeout; |
| 3187 | long numreplicas, ackreplicas; |
| 3188 | long long offset = c->woff; |
| 3189 | |
| 3190 | if (server.masterhost) { |
| 3191 | addReplyError(c,"WAIT cannot be used with replica instances. Please also note that since Redis 4.0 if a replica is configured to be writable (which is not the default) writes to replicas are just local and are not propagated."); |
| 3192 | return; |
| 3193 | } |
| 3194 | |
| 3195 | /* Argument parsing. */ |
| 3196 | if (getLongFromObjectOrReply(c,c->argv[1],&numreplicas,NULL) != C_OK) |
| 3197 | return; |
| 3198 | if (getTimeoutFromObjectOrReply(c,c->argv[2],&timeout,UNIT_MILLISECONDS) |
| 3199 | != C_OK) return; |
| 3200 | |
| 3201 | /* First try without blocking at all. */ |
| 3202 | ackreplicas = replicationCountAcksByOffset(c->woff); |
| 3203 | if (ackreplicas >= numreplicas || c->flags & CLIENT_MULTI) { |
| 3204 | addReplyLongLong(c,ackreplicas); |
| 3205 | return; |
| 3206 | } |
| 3207 | |
| 3208 | /* Otherwise block the client and put it into our list of clients |
| 3209 | * waiting for ack from slaves. */ |
| 3210 | c->bpop.timeout = timeout; |
| 3211 | c->bpop.reploffset = offset; |
| 3212 | c->bpop.numreplicas = numreplicas; |
| 3213 | listAddNodeHead(server.clients_waiting_acks,c); |
| 3214 | blockClient(c,BLOCKED_WAIT); |
| 3215 | |
| 3216 | /* Make sure that the server will send an ACK request to all the slaves |
| 3217 | * before returning to the event loop. */ |
| 3218 | replicationRequestAckFromSlaves(); |
| 3219 | } |
| 3220 | |
| 3221 | /* This is called by unblockClient() to perform the blocking op type |
| 3222 | * specific cleanup. We just remove the client from the list of clients |
nothing calls this directly
no test coverage detected