diff options
author | michael-grunder <michael.grunder@gmail.com> | 2014-07-17 03:57:25 +0400 |
---|---|---|
committer | michael-grunder <michael.grunder@gmail.com> | 2015-05-06 01:05:29 +0300 |
commit | a65301bc2e9b678896675584e3a8e3219aa221f7 (patch) | |
tree | 3d87402ebe836cc74b83b3afc0a24d3c0ffad04f /cluster_library.c | |
parent | 5ed61ea3055c21cd635f1d8d1f103f81a38888a8 (diff) |
Update redirection logic to throw on CLUSTERDOWN
When Redis Cluster responds with a CLUSTERDOWN error, we should
throw an exception. It seems that in the current state of cluster
(during slave election), it will enter a CLUSTERDOWN state for a
short period of time.
This allows clients to trap the exception and then either wait and
try again, or do something else.
Diffstat (limited to 'cluster_library.c')
-rw-r--r-- | cluster_library.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/cluster_library.c b/cluster_library.c index 16f02d0f..155f026b 100644 --- a/cluster_library.c +++ b/cluster_library.c @@ -372,6 +372,13 @@ void cluster_multi_fini(clusterMultiCmd *mc) { static void cluster_set_err(redisCluster *c, char *err, int err_len) { if(err && err_len>0) { + if(err_len >= sizeof("CLUSTERDOWN")-1 && + !memcmp(err, "CLUSTERDOWN", sizeof("CLUSTERDOWN")-1)) + { + c->clusterdown = 1; + return; + } + if(c->err == NULL) { c->err = emalloc(err_len+1); } else if(err_len > c->err_len) { @@ -380,8 +387,6 @@ static void cluster_set_err(redisCluster *c, char *err, int err_len) memcpy(c->err,err,err_len); c->err[err_len]='\0'; c->err_len = err_len; -php_printf("Set error to: %s\n", c->err); - } else { if(c->err) efree(c->err); c->err = NULL; @@ -1280,13 +1285,8 @@ PHPAPI short cluster_send_command(redisCluster *c, short slot, const char *cmd, // Check the response from the slot we ended up querying. resp = cluster_check_response(c, slot, &c->reply_type TSRMLS_CC); - // If we're getting an error condition, impose a slight delay before - // we try again (e.g. server went down, election in process). If the - // data has been moved, update node configuration, and if ASK has been - // encountered, we'll just try again at that slot. - if(resp == -1) { - sleep(1); - } else if(resp == 1) { + /* Handle MOVED or ASKING redirection */ + if(resp == 1) { // If we get a MOVED response inside of a transaction, we have to // abort, because the transaction would be invalid. if(c->flags->mode == MULTI) { @@ -1302,7 +1302,14 @@ PHPAPI short cluster_send_command(redisCluster *c, short slot, const char *cmd, } slot = c->redir_slot; } - } while(resp != 0); + } while(resp != 0 && !c->clusterdown); + + // If we've detected the cluster is down, throw an exception + if(c->clusterdown) { + zend_throw_exception(redis_cluster_exception_ce, + "The Redis Cluster is down (CLUSTERDOWN)", 0 TSRMLS_CC); + return -1; + } // Inform the cluster where to read the rest of our response, // and clear out redirection flag. |