mirror of
https://github.com/fluencelabs/redis
synced 2025-06-29 08:51:33 +00:00
WAIT command: synchronous replication for Redis.
This commit is contained in:
29
src/redis.c
29
src/redis.c
@ -263,7 +263,8 @@ struct redisCommand redisCommandTable[] = {
|
||||
{"script",scriptCommand,-2,"ras",0,NULL,0,0,0,0,0},
|
||||
{"time",timeCommand,1,"rR",0,NULL,0,0,0,0,0},
|
||||
{"bitop",bitopCommand,-4,"wm",0,NULL,2,-1,1,0,0},
|
||||
{"bitcount",bitcountCommand,-2,"r",0,NULL,1,1,1,0,0}
|
||||
{"bitcount",bitcountCommand,-2,"r",0,NULL,1,1,1,0,0},
|
||||
{"wait",waitCommand,3,"rs",0,NULL,0,0,0,0,0}
|
||||
};
|
||||
|
||||
/*============================ Utility functions ============================ */
|
||||
@ -1200,8 +1201,29 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
|
||||
if (server.active_expire_enabled && server.masterhost == NULL)
|
||||
activeExpireCycle(ACTIVE_EXPIRE_CYCLE_FAST);
|
||||
|
||||
/* Send all the slaves an ACK request if at least one client blocked
|
||||
* during the previous event loop iteration. */
|
||||
if (server.get_ack_from_slaves) {
|
||||
robj *argv[3];
|
||||
|
||||
argv[0] = createStringObject("REPLCONF",8);
|
||||
argv[1] = createStringObject("GETACK",6);
|
||||
argv[2] = createStringObject("*",1); /* Not used argument. */
|
||||
replicationFeedSlaves(server.slaves, server.slaveseldb, argv, 3);
|
||||
decrRefCount(argv[0]);
|
||||
decrRefCount(argv[1]);
|
||||
decrRefCount(argv[2]);
|
||||
server.get_ack_from_slaves = 0;
|
||||
}
|
||||
|
||||
/* Unblock all the clients blocked for synchronous replication
|
||||
* in WAIT. */
|
||||
if (listLength(server.clients_waiting_acks))
|
||||
processClientsWaitingReplicas();
|
||||
|
||||
/* Try to process pending commands for clients that were just unblocked. */
|
||||
processUnblockedClients();
|
||||
if (listLength(server.unblocked_clients))
|
||||
processUnblockedClients();
|
||||
|
||||
/* Write the AOF buffer on disk */
|
||||
flushAppendOnlyFile(0);
|
||||
@ -1557,6 +1579,8 @@ void initServer() {
|
||||
server.slaveseldb = -1; /* Force to emit the first SELECT command. */
|
||||
server.unblocked_clients = listCreate();
|
||||
server.ready_keys = listCreate();
|
||||
server.clients_waiting_acks = listCreate();
|
||||
server.get_ack_from_slaves = 0;
|
||||
|
||||
createSharedObjects();
|
||||
adjustOpenFilesLimit();
|
||||
@ -2079,6 +2103,7 @@ int processCommand(redisClient *c) {
|
||||
addReply(c,shared.queued);
|
||||
} else {
|
||||
call(c,REDIS_CALL_FULL);
|
||||
c->woff = server.master_repl_offset;
|
||||
if (listLength(server.ready_keys))
|
||||
handleClientsBlockedOnLists();
|
||||
}
|
||||
|
Reference in New Issue
Block a user