Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c75b3b9

Browse files
committed
Connection limit for pool.
1 parent 6cbe2a6 commit c75b3b9

3 files changed

Lines changed: 36 additions & 15 deletions

File tree

common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,11 @@ typedef struct {
736736
} RedisSock;
737737
/* }}} */
738738

739+
typedef struct {
740+
zend_llist list;
741+
int nb_active;
742+
} ConnectionPool;
743+
739744
#if (PHP_MAJOR_VERSION < 7)
740745
typedef struct {
741746
zend_object std;

library.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,19 @@ extern zend_class_entry *redis_exception_ce;
6363

6464
extern int le_redis_pconnect;
6565

66-
static zend_llist *
66+
static ConnectionPool *
6767
redis_sock_get_connection_pool(RedisSock *redis_sock TSRMLS_DC)
6868
{
6969
zend_string *persistent_id = strpprintf(0, "phpredis_%s:%d", ZSTR_VAL(redis_sock->host), redis_sock->port);
7070
zend_resource *le = zend_hash_find_ptr(&EG(persistent_list), persistent_id);
7171
if (!le) {
72-
zend_llist *list = pecalloc(1, sizeof(*list) + sizeof(*le), 1);
73-
zend_llist_init(list, sizeof(php_stream *), NULL, 1);
74-
le = (zend_resource *)((char *)list + sizeof(*list));
72+
ConnectionPool *p = pecalloc(1, sizeof(*p) + sizeof(*le), 1);
73+
zend_llist_init(&p->list, sizeof(php_stream *), NULL, 1);
74+
le = (zend_resource *)((char *)p + sizeof(*p));
7575
le->type = le_redis_pconnect;
76-
le->ptr = list;
76+
le->ptr = p;
7777
zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(persistent_id), ZSTR_LEN(persistent_id), le, sizeof(*le));
78+
p->nb_active = 0;
7879
}
7980
zend_string_release(persistent_id);
8081
return le->ptr;
@@ -1765,8 +1766,8 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
17651766
zend_string *persistent_id = NULL;
17661767
char host[1024];
17671768
const char *fmtstr = "%s:%d";
1768-
int host_len, usocket = 0, err = 0;
1769-
int tcp_flag = 1;
1769+
int host_len, usocket = 0, err = 0, tcp_flag = 1;
1770+
ConnectionPool *p = NULL;
17701771
#if (PHP_MAJOR_VERSION < 7)
17711772
char *estr = NULL;
17721773
#else
@@ -1796,16 +1797,23 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
17961797

17971798
if (redis_sock->persistent) {
17981799
if (INI_INT("redis.pconnect.pooling_enabled")) {
1799-
zend_llist *list = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
1800-
if (zend_llist_count(list) > 0) {
1801-
redis_sock->stream = *(php_stream **)zend_llist_get_last(list);
1802-
zend_llist_remove_tail(list);
1800+
p = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
1801+
if (zend_llist_count(&p->list) > 0) {
1802+
redis_sock->stream = *(php_stream **)zend_llist_get_last(&p->list);
1803+
zend_llist_remove_tail(&p->list);
18031804
/* Check socket liveness using 0 second timeout */
18041805
if (php_stream_set_option(redis_sock->stream, PHP_STREAM_OPTION_CHECK_LIVENESS, 0, NULL) == PHP_STREAM_OPTION_RETURN_OK) {
18051806
redis_sock->status = REDIS_SOCK_STATUS_CONNECTED;
18061807
return SUCCESS;
18071808
}
18081809
php_stream_pclose(redis_sock->stream);
1810+
p->nb_active--;
1811+
}
1812+
1813+
int limit = INI_INT("redis.pconnect.connection_limit");
1814+
if (limit > 0 && p->nb_active >= limit) {
1815+
redis_sock_set_err(redis_sock, "Connection limit reached", sizeof("Connection limit reached") - 1);
1816+
return FAILURE;
18091817
}
18101818

18111819
gettimeofday(&tv, NULL);
@@ -1847,6 +1855,8 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
18471855
return FAILURE;
18481856
}
18491857

1858+
if (p) p->nb_active++;
1859+
18501860
/* Attempt to set TCP_NODELAY/TCP_KEEPALIVE if we're not using a unix socket. */
18511861
if (!usocket) {
18521862
php_netstream_data_t *sock = (php_netstream_data_t*)redis_sock->stream->abstract;
@@ -1902,11 +1912,15 @@ redis_sock_disconnect(RedisSock *redis_sock, int force TSRMLS_DC)
19021912
return FAILURE;
19031913
} else if (redis_sock->stream) {
19041914
if (redis_sock->persistent) {
1915+
ConnectionPool *p = NULL;
1916+
if (INI_INT("redis.pconnect.pooling_enabled")) {
1917+
p = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
1918+
}
19051919
if (force) {
19061920
php_stream_pclose(redis_sock->stream);
1907-
} else if (INI_INT("redis.pconnect.pooling_enabled")) {
1908-
zend_llist *list = redis_sock_get_connection_pool(redis_sock TSRMLS_CC);
1909-
zend_llist_prepend_element(list, &redis_sock->stream);
1921+
if (p) p->nb_active--;
1922+
} else if (p) {
1923+
zend_llist_prepend_element(&p->list, &redis_sock->stream);
19101924
}
19111925
} else {
19121926
php_stream_close(redis_sock->stream);

redis.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ PHP_INI_BEGIN()
8181

8282
/* redis pconnect */
8383
PHP_INI_ENTRY("redis.pconnect.pooling_enabled", "0", PHP_INI_ALL, NULL)
84+
PHP_INI_ENTRY("redis.pconnect.connection_limit", "0", PHP_INI_ALL, NULL)
8485

8586
/* redis session */
8687
PHP_INI_ENTRY("redis.session.locking_enabled", "0", PHP_INI_ALL, NULL)
@@ -754,7 +755,8 @@ static ZEND_RSRC_DTOR_FUNC(redis_connections_pool_dtor)
754755
#endif
755756

756757
if (res->ptr) {
757-
zend_llist_destroy(res->ptr);
758+
ConnectionPool *p = res->ptr;
759+
zend_llist_destroy(&p->list);
758760
pefree(res->ptr, 1);
759761
}
760762
}

0 commit comments

Comments
 (0)