Handle connection errors better in blocking mode as well

This commit is contained in:
Mark Nunberg 2018-03-05 12:17:49 +02:00
parent 5e6bbf8c60
commit cbe4ae63ae
3 changed files with 15 additions and 6 deletions

View File

@ -508,7 +508,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
static int __redisAsyncHandleConnect(redisAsyncContext *ac) { static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
int completed = 0; int completed = 0;
redisContext *c = &(ac->c); redisContext *c = &(ac->c);
if (redisFinishAsyncConnect(c, &completed) == REDIS_ERR) { if (redisCheckConnectDone(c, &completed) == REDIS_ERR) {
/* Error! */ /* Error! */
redisCheckSocketError(c); redisCheckSocketError(c);
if (ac->onConnect) ac->onConnect(ac, REDIS_ERR); if (ac->onConnect) ac->onConnect(ac, REDIS_ERR);

17
net.c
View File

@ -221,8 +221,10 @@ static int redisContextWaitReady(redisContext *c, long msec) {
return REDIS_ERR; return REDIS_ERR;
} }
if (redisCheckSocketError(c) != REDIS_OK) if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) {
redisCheckSocketError(c);
return REDIS_ERR; return REDIS_ERR;
}
return REDIS_OK; return REDIS_OK;
} }
@ -232,7 +234,7 @@ static int redisContextWaitReady(redisContext *c, long msec) {
return REDIS_ERR; return REDIS_ERR;
} }
int redisFinishAsyncConnect(redisContext *c, int *completed) { int redisCheckConnectDone(redisContext *c, int *completed) {
int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen); int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen);
if (rc == 0) { if (rc == 0) {
*completed = 1; *completed = 1;
@ -410,8 +412,14 @@ addrretry:
if (errno == EHOSTUNREACH) { if (errno == EHOSTUNREACH) {
redisContextCloseFd(c); redisContextCloseFd(c);
continue; continue;
} else if (errno == EINPROGRESS && !blocking) { } else if (errno == EINPROGRESS) {
/* This is ok. */ if (blocking) {
goto wait_for_ready;
}
/* This is ok.
* Note that even when it's in blocking mode, we unset blocking
* for `connect()`
*/
} else if (errno == EADDRNOTAVAIL && reuseaddr) { } else if (errno == EADDRNOTAVAIL && reuseaddr) {
if (++reuses >= REDIS_CONNECT_RETRIES) { if (++reuses >= REDIS_CONNECT_RETRIES) {
goto error; goto error;
@ -420,6 +428,7 @@ addrretry:
goto addrretry; goto addrretry;
} }
} else { } else {
wait_for_ready:
if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
goto error; goto error;
} }

2
net.h
View File

@ -45,6 +45,6 @@ int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
const char *source_addr); const char *source_addr);
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout);
int redisKeepAlive(redisContext *c, int interval); int redisKeepAlive(redisContext *c, int interval);
int redisFinishAsyncConnect(redisContext *c, int *completed); int redisCheckConnectDone(redisContext *c, int *completed);
#endif #endif