Skip to content

Commit afcb303

Browse files
authored
Merge pull request phpredis#1823 from phpredis/liveness-check
Refactor redis_sock_check_liveness
2 parents c9ed151 + c595064 commit afcb303

File tree

1 file changed

+57
-26
lines changed

1 file changed

+57
-26
lines changed

library.c

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -685,19 +685,6 @@ redis_sock_read(RedisSock *redis_sock, int *buf_len)
685685
return NULL;
686686
}
687687

688-
static int redis_sock_read_cmp(RedisSock *redis_sock, const char *cmp, int cmplen) {
689-
char *resp;
690-
int len, rv = FAILURE;
691-
692-
if ((resp = redis_sock_read(redis_sock, &len)) == NULL)
693-
return FAILURE;
694-
695-
rv = len == cmplen && !memcmp(resp, cmp, cmplen) ? SUCCESS : FAILURE;
696-
697-
efree(resp);
698-
return rv;
699-
}
700-
701688
/* A simple union to store the various arg types we might handle in our
702689
* redis_spprintf command formatting function */
703690
union resparg {
@@ -2129,16 +2116,21 @@ static int redis_stream_liveness_check(php_stream *stream) {
21292116
static int
21302117
redis_sock_check_liveness(RedisSock *redis_sock)
21312118
{
2132-
char id[64], ok;
2119+
char id[64], inbuf[4096];
21332120
int idlen, auth;
21342121
smart_string cmd = {0};
2122+
size_t len;
21352123

21362124
/* Short circuit if we detect the stream has gone bad or if the user has
21372125
* configured persistent connection "YOLO mode". */
2138-
if (redis_stream_liveness_check(redis_sock->stream) != SUCCESS)
2139-
return FAILURE;
2140-
else if (!INI_INT("redis.pconnect.echo_check_liveness"))
2126+
if (redis_stream_liveness_check(redis_sock->stream) != SUCCESS) {
2127+
goto failure;
2128+
}
2129+
2130+
redis_sock->status = REDIS_SOCK_STATUS_CONNECTED;
2131+
if (!INI_INT("redis.pconnect.echo_check_liveness")) {
21412132
return SUCCESS;
2133+
}
21422134

21432135
/* AUTH (if we need it) */
21442136
auth = redis_sock_append_auth(redis_sock, &cmd);
@@ -2149,12 +2141,55 @@ redis_sock_check_liveness(RedisSock *redis_sock)
21492141
redis_cmd_append_sstr(&cmd, id, idlen);
21502142

21512143
/* Send command(s) and make sure we can consume reply(ies) */
2152-
ok = (redis_sock_write(redis_sock, cmd.c, cmd.len) >= 0) &&
2153-
(!auth || redis_sock_read_ok(redis_sock) == SUCCESS) &&
2154-
(redis_sock_read_cmp(redis_sock, id, idlen) == SUCCESS);
2155-
2144+
if (redis_sock_write(redis_sock, cmd.c, cmd.len) < 0) {
2145+
smart_string_free(&cmd);
2146+
goto failure;
2147+
}
21562148
smart_string_free(&cmd);
2157-
return ok ? SUCCESS : FAILURE;
2149+
2150+
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
2151+
goto failure;
2152+
}
2153+
2154+
if (auth) {
2155+
if (strncmp(inbuf, "+OK", 3) == 0 || strncmp(inbuf, "-ERR Client sent AUTH", 21) == 0) {
2156+
/* successfully authenticated or authentication isn't required */
2157+
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
2158+
goto failure;
2159+
}
2160+
} else if (strncmp(inbuf, "-NOAUTH", 7) == 0) {
2161+
/* connection is fine but authentication failed, next command must fails too */
2162+
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0 || strncmp(inbuf, "-NOAUTH", 7) != 0) {
2163+
goto failure;
2164+
}
2165+
return SUCCESS;
2166+
} else {
2167+
goto failure;
2168+
}
2169+
redis_sock->status = REDIS_SOCK_STATUS_READY;
2170+
} else {
2171+
if (strncmp(inbuf, "-NOAUTH", 7) == 0) {
2172+
/* connection is fine but authentication required */
2173+
return SUCCESS;
2174+
}
2175+
}
2176+
2177+
/* check echo response */
2178+
if (*inbuf != TYPE_BULK || atoi(inbuf + 1) != idlen ||
2179+
redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0 ||
2180+
strncmp(inbuf, id, idlen) != 0
2181+
) {
2182+
goto failure;
2183+
}
2184+
2185+
return SUCCESS;
2186+
failure:
2187+
redis_sock->status = REDIS_SOCK_STATUS_DISCONNECTED;
2188+
if (redis_sock->stream) {
2189+
php_stream_pclose(redis_sock->stream);
2190+
redis_sock->stream = NULL;
2191+
}
2192+
return FAILURE;
21582193
}
21592194

21602195
/**
@@ -2207,11 +2242,7 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock)
22072242
zend_llist_remove_tail(&p->list);
22082243

22092244
if (redis_sock_check_liveness(redis_sock) == SUCCESS) {
2210-
redis_sock->status = REDIS_SOCK_STATUS_READY;
22112245
return SUCCESS;
2212-
} else if (redis_sock->stream) {
2213-
php_stream_pclose(redis_sock->stream);
2214-
redis_sock->stream = NULL;
22152246
}
22162247
p->nb_active--;
22172248
}

0 commit comments

Comments
 (0)