diff options
author | Jan-Erik Rediger <janerik@fnordig.de> | 2015-04-16 19:28:12 +0200 |
---|---|---|
committer | Jan-Erik Rediger <janerik@fnordig.de> | 2015-04-16 21:00:30 +0200 |
commit | d9e0b0f6abfbb8918f73607bdfcc707d0df3fd41 (patch) | |
tree | 18a642cfca4697e0349767238ddf6d6ff368ea38 /hiredis.c | |
parent | b872919463fbc04c3a8fde113cb9ae89dfcb3859 (diff) |
Implement a reconnect method for the client context
Originally implemented by @abedra as part of #306.
In case a write or read times out, we force an error state, because we
can't guarantuee that the next read will get the right data.
Instead we need to reconnect to have a clean-state connection, which is
now easily possible with this method.
Diffstat (limited to 'hiredis.c')
-rw-r--r-- | hiredis.c | 40 |
1 files changed, 40 insertions, 0 deletions
@@ -598,6 +598,10 @@ static redisContext *redisContextInit(void) { c->errstr[0] = '\0'; c->obuf = sdsempty(); c->reader = redisReaderCreate(); + c->tcp.host = NULL; + c->tcp.source_addr = NULL; + c->unix.path = NULL; + c->timeout = NULL; if (c->obuf == NULL || c->reader == NULL) { redisFree(c); @@ -616,6 +620,14 @@ void redisFree(redisContext *c) { sdsfree(c->obuf); if (c->reader != NULL) redisReaderFree(c->reader); + if (c->tcp.host) + free(c->tcp.host); + if (c->tcp.source_addr) + free(c->tcp.source_addr); + if (c->unix.path) + free(c->unix.path); + if (c->timeout) + free(c->timeout); free(c); } @@ -626,6 +638,34 @@ int redisFreeKeepFd(redisContext *c) { return fd; } +int redisReconnect(redisContext *c) { + c->err = 0; + memset(c->errstr, '\0', strlen(c->errstr)); + + if (c->fd > 0) { + close(c->fd); + } + + sdsfree(c->obuf); + redisReaderFree(c->reader); + + c->obuf = sdsempty(); + c->reader = redisReaderCreate(); + + if (c->connection_type == REDIS_CONN_TCP) { + return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port, + c->timeout, c->tcp.source_addr); + } else if (c->connection_type == REDIS_CONN_UNIX) { + return redisContextConnectUnix(c, c->unix.path, c->timeout); + } else { + /* Something bad happened here and shouldn't have. There isn't + enough information in the context to reconnect. */ + __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect"); + } + + return REDIS_ERR; +} + /* Connect to a Redis instance. On error the field error in the returned * context will be set to the return value of the error function. * When no set of reply functions is given, the default set will be used. */ |