Skip to content

Commit

Permalink
MIGRATE: retry one time on I/O error.
Browse files Browse the repository at this point in the history
Now that we cache connections, a retry attempt makes sure that the
operation don't fail just because there is an existing connection error
on the socket, like the other end closing the connection.

Unfortunately this condition is not detectable using
getsockopt(SO_ERROR), so the only option left is to retry.

We don't retry on timeouts.
  • Loading branch information
antirez committed Nov 14, 2012
1 parent 17411f7 commit 2feef47
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/cluster.c
Expand Up @@ -1741,12 +1741,19 @@ void migrateCloseTimedoutSockets(void) {

/* MIGRATE host port key dbid timeout [COPY | REPLACE] */
void migrateCommand(redisClient *c) {
int fd, copy = 0, replace = 0, j;
int fd, copy, replace, j;
long timeout;
long dbid;
long long ttl = 0, expireat;
long long ttl, expireat;
robj *o;
rio cmd, payload;
int retry_num = 0;

try_again:
/* Initialization */
copy = 0;
replace = 0;
ttl = 0;

/* Parse additional options */
for (j = 6; j < c->argc; j++) {
Expand Down Expand Up @@ -1809,6 +1816,7 @@ void migrateCommand(redisClient *c) {
redisAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"REPLACE",7));

/* Tranfer the query to the other node in 64K chunks. */
errno = 0;
{
sds buf = cmd.io.buffer.ptr;
size_t pos = 0, towrite;
Expand Down Expand Up @@ -1857,15 +1865,19 @@ void migrateCommand(redisClient *c) {
return;

socket_wr_err:
addReplySds(c,sdsnew("-IOERR error or timeout writing to target instance\r\n"));
sdsfree(cmd.io.buffer.ptr);
migrateCloseSocket(c->argv[1],c->argv[2]);
if (errno != ETIMEDOUT && retry_num++ == 0) goto try_again;
addReplySds(c,
sdsnew("-IOERR error or timeout writing to target instance\r\n"));
return;

socket_rd_err:
addReplySds(c,sdsnew("-IOERR error or timeout reading from target node\r\n"));
sdsfree(cmd.io.buffer.ptr);
migrateCloseSocket(c->argv[1],c->argv[2]);
if (errno != ETIMEDOUT && retry_num++ == 0) goto try_again;
addReplySds(c,
sdsnew("-IOERR error or timeout reading from target node\r\n"));
return;
}

Expand Down

0 comments on commit 2feef47

Please sign in to comment.