Skip to content

Commit 99ebd0c

Browse files
yatsukhnenkomichael-grunder
authored andcommitted
Add helper function to check liveness of connection after getting it from the pool. Send `AUTH` before `PING` if necessary in pipeline.
1 parent 5c7bc39 commit 99ebd0c

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

library.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,7 @@ redis_sock_auth(RedisSock *redis_sock)
118118
char *cmd, *response;
119119
int cmd_len, response_len;
120120

121-
cmd_len = redis_spprintf(redis_sock, NULL, &cmd, "AUTH", "s",
122-
ZSTR_VAL(redis_sock->auth), ZSTR_LEN(redis_sock->auth));
121+
cmd_len = redis_spprintf(redis_sock, NULL, &cmd, "AUTH", "S", redis_sock->auth);
123122

124123
if (redis_sock_write(redis_sock, cmd, cmd_len) < 0) {
125124
efree(cmd);
@@ -1798,6 +1797,50 @@ redis_sock_create(char *host, int host_len, int port,
17981797
return redis_sock;
17991798
}
18001799

1800+
static int
1801+
redis_sock_check_liveness(RedisSock *redis_sock)
1802+
{
1803+
char inbuf[4096], uniqid[32], *response;
1804+
int uniqid_len, response_len;
1805+
smart_string cmd = {0};
1806+
struct timeval tv;
1807+
size_t len;
1808+
1809+
if (redis_sock->auth) {
1810+
redis_cmd_init_sstr(&cmd, 1, "AUTH", sizeof("AUTH") - 1);
1811+
redis_cmd_append_sstr(&cmd, ZSTR_VAL(redis_sock->auth), ZSTR_LEN(redis_sock->auth));
1812+
}
1813+
gettimeofday(&tv, NULL);
1814+
uniqid_len = sprintf(uniqid, "%08lx%05lx", tv.tv_sec, tv.tv_usec);
1815+
redis_cmd_init_sstr(&cmd, 1, "PING", sizeof("PING") - 1);
1816+
redis_cmd_append_sstr(&cmd, uniqid, uniqid_len);
1817+
smart_string_0(&cmd);
1818+
1819+
if (redis_sock_write(redis_sock, cmd.c, cmd.len) < 0) {
1820+
smart_string_free(&cmd);
1821+
return FAILURE;
1822+
}
1823+
smart_string_free(&cmd);
1824+
1825+
if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
1826+
return FAILURE;
1827+
} else if (redis_sock->auth) {
1828+
if (strncmp(inbuf, "+OK", 3) != 0) {
1829+
return FAILURE;
1830+
} else if (redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0) {
1831+
return FAILURE;
1832+
}
1833+
}
1834+
if (*inbuf != TYPE_BULK ||
1835+
atoi(inbuf + 1) != uniqid_len ||
1836+
redis_sock_gets(redis_sock, inbuf, sizeof(inbuf) - 1, &len) < 0 ||
1837+
strncmp(inbuf, uniqid, uniqid_len) != 0
1838+
) {
1839+
return FAILURE;
1840+
}
1841+
return SUCCESS;
1842+
}
1843+
18011844
/**
18021845
* redis_sock_connect
18031846
*/
@@ -1843,8 +1886,8 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock)
18431886
if (zend_llist_count(&p->list) > 0) {
18441887
redis_sock->stream = *(php_stream **)zend_llist_get_last(&p->list);
18451888
zend_llist_remove_tail(&p->list);
1846-
/* Check socket liveness using 0 second timeout */
1847-
if (php_stream_set_option(redis_sock->stream, PHP_STREAM_OPTION_CHECK_LIVENESS, 0, NULL) == PHP_STREAM_OPTION_RETURN_OK) {
1889+
1890+
if (redis_sock_check_liveness(redis_sock) == SUCCESS) {
18481891
redis_sock->status = REDIS_SOCK_STATUS_CONNECTED;
18491892
return SUCCESS;
18501893
}

0 commit comments

Comments
 (0)