Skip to content

Commit

Permalink
slaveTryPartialResynchronization and syncWithMaster: better synergy.
Browse files Browse the repository at this point in the history
It is simpler if removing the read event handler from the FD is up to
slaveTryPartialResynchronization, after all it is only called in the
context of syncWithMaster.

This commit also makes sure that on error all the event handlers are
removed from the socket before closing it.
  • Loading branch information
antirez committed Aug 7, 2015
1 parent 88c716a commit bea1259
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions src/replication.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,14 @@ char *sendSynchronousCommand(int flags, int fd, ...) {
* the caller should fall back to SYNC.
* PSYNC_WRITE_ERR: There was an error writing the command to the socket.
* PSYNC_WAIT_REPLY: Call again the function with read_reply set to 1.
*
* Notable side effects:
*
* 1) As a side effect of the function call the function removes the readable
* event handler from "fd", unless the return value is PSYNC_WAIT_REPLY.
* 2) server.repl_master_initial_offset is set to the right value according
* to the master reply. This will be used to populate the 'server.master'
* structure replication offset.
*/

#define PSYNC_WRITE_ERROR 0
Expand Down Expand Up @@ -1254,6 +1262,7 @@ int slaveTryPartialResynchronization(int fd, int read_reply) {
if (reply != NULL) {
serverLog(LL_WARNING,"Unable to send PSYNC to master: %s",reply);
sdsfree(reply);
aeDeleteFileEvent(server.el,fd,AE_READABLE);
return PSYNC_WRITE_ERROR;
}
return PSYNC_WAIT_REPLY;
Expand All @@ -1268,6 +1277,8 @@ int slaveTryPartialResynchronization(int fd, int read_reply) {
return PSYNC_WAIT_REPLY;
}

aeDeleteFileEvent(server.el,fd,AE_READABLE);

if (!strncmp(reply,"+FULLRESYNC",11)) {
char *runid = NULL, *offset = NULL;

Expand Down Expand Up @@ -1348,7 +1359,6 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &errlen) == -1)
sockerr = errno;
if (sockerr) {
aeDeleteFileEvent(server.el,fd,AE_READABLE|AE_WRITABLE);
serverLog(LL_WARNING,"Error condition on socket for SYNC: %s",
strerror(sockerr));
goto error;
Expand Down Expand Up @@ -1490,20 +1500,11 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
goto error;
}

/* Delete the readable event, we no longer need it now that there is
* the last reply to read. */
aeDeleteFileEvent(server.el,fd,AE_READABLE);
psync_result = slaveTryPartialResynchronization(fd,1);
if (psync_result == PSYNC_WAIT_REPLY) {
if (aeCreateFileEvent(server.el,fd,AE_READABLE,
syncWithMaster,NULL) == AE_ERR)
{
serverLog(LL_WARNING,"Failed to reinstall the read event in "
"PSYNC_WAIT_REPLY state.");
goto error;
}
return; /* Try again later... */
}
if (psync_result == PSYNC_WAIT_REPLY) return; /* Try again later... */

/* Note: if PSYNC does not return WAIT_REPLY, it will take care of
* uninstalling the read handler from the file descriptor. */

if (psync_result == PSYNC_CONTINUE) {
serverLog(LL_NOTICE, "MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.");
Expand Down Expand Up @@ -1562,6 +1563,7 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
return;

error:
aeDeleteFileEvent(server.el,fd,AE_READABLE|AE_WRITABLE);
close(fd);
server.repl_transfer_s = -1;
server.repl_state = REPL_STATE_CONNECT;
Expand Down

0 comments on commit bea1259

Please sign in to comment.