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

Skip to content

Commit 68c5851

Browse files
committed
MOD: Add tcp_keepalive option to redis sock
1 parent 75e7c81 commit 68c5851

4 files changed

Lines changed: 36 additions & 2 deletions

File tree

common.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,8 @@ typedef enum _PUBSUB_TYPE {
478478
#define REDIS_OPT_READ_TIMEOUT 3
479479
#define REDIS_OPT_SCAN 4
480480
#define REDIS_OPT_FAILOVER 5
481-
#define REDIS_OPT_COMPRESSION 6
481+
#define REDIS_OPT_TCP_KEEPALIVE 6
482+
#define REDIS_OPT_COMPRESSION 7
482483

483484
/* cluster options */
484485
#define REDIS_FAILOVER_NONE 0
@@ -674,6 +675,7 @@ typedef struct {
674675
int scan;
675676

676677
int readonly;
678+
int tcp_keepalive;
677679
} RedisSock;
678680
/* }}} */
679681

library.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,7 @@ redis_sock_create(char *host, int host_len, unsigned short port,
14021402
redis_sock->scan = REDIS_SCAN_NORETRY;
14031403

14041404
redis_sock->readonly = 0;
1405+
redis_sock->tcp_keepalive = 0;
14051406

14061407
return redis_sock;
14071408
}
@@ -1470,11 +1471,13 @@ PHP_REDIS_API int redis_sock_connect(RedisSock *redis_sock TSRMLS_DC)
14701471
return -1;
14711472
}
14721473

1473-
/* Attempt to set TCP_NODELAY if we're not using a unix socket. */
1474+
/* Attempt to set TCP_NODELAY/TCP_KEEPALIVE if we're not using a unix socket. */
14741475
sock = (php_netstream_data_t*)redis_sock->stream->abstract;
14751476
if (!usocket) {
14761477
err = setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, (char *) &tcp_flag, sizeof(int));
14771478
PHPREDIS_NOTUSED(err);
1479+
err = setsockopt(sock->socket, SOL_SOCKET, SO_KEEPALIVE, (const void *) &redis_sock->tcp_keepalive, sizeof(int));
1480+
PHPREDIS_NOTUSED(err);
14781481
}
14791482

14801483
php_stream_auto_cleanup(redis_sock->stream);

redis.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ static void add_class_constants(zend_class_entry *ce, int is_cluster TSRMLS_DC)
676676
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_SERIALIZER"), REDIS_OPT_SERIALIZER TSRMLS_CC);
677677
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_PREFIX"), REDIS_OPT_PREFIX TSRMLS_CC);
678678
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_READ_TIMEOUT"), REDIS_OPT_READ_TIMEOUT TSRMLS_CC);
679+
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_TCP_KEEPALIVE"), REDIS_OPT_TCP_KEEPALIVE TSRMLS_CC);
679680
zend_declare_class_constant_long(ce, ZEND_STRL("OPT_COMPRESSION"), REDIS_OPT_COMPRESSION TSRMLS_CC);
680681

681682
/* serializer */

redis_commands.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#endif
2424

2525
#include "redis_commands.h"
26+
27+
#include "php_network.h"
28+
#include <netinet/tcp.h> /* TCP_KEEPALIVE */
29+
2630
#include <zend_exceptions.h>
2731

2832
/* Local passthrough macro for command construction. Given that these methods
@@ -3019,6 +3023,8 @@ void redis_getoption_handler(INTERNAL_FUNCTION_PARAMETERS,
30193023
RETURN_NULL();
30203024
case REDIS_OPT_READ_TIMEOUT:
30213025
RETURN_DOUBLE(redis_sock->read_timeout);
3026+
case REDIS_OPT_TCP_KEEPALIVE:
3027+
RETURN_LONG(redis_sock->tcp_keepalive);
30223028
case REDIS_OPT_SCAN:
30233029
RETURN_LONG(redis_sock->scan);
30243030
case REDIS_OPT_FAILOVER:
@@ -3036,6 +3042,8 @@ void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
30363042
char *val_str;
30373043
struct timeval read_tv;
30383044
strlen_t val_len;
3045+
int tcp_keepalive = 0;
3046+
php_netstream_data_t *sock;
30393047

30403048
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &option,
30413049
&val_str, &val_len) == FAILURE)
@@ -3086,6 +3094,26 @@ void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
30863094
&read_tv);
30873095
}
30883096
RETURN_TRUE;
3097+
case REDIS_OPT_TCP_KEEPALIVE:
3098+
3099+
/* Don't set TCP_KEEPALIVE if we're using a unix socket. */
3100+
if (ZSTR_VAL(redis_sock->host)[0] == '/' && redis_sock->port < 1) {
3101+
RETURN_FALSE;
3102+
}
3103+
tcp_keepalive = atol(val_str) > 0 ? 1 : 0;
3104+
if (redis_sock->tcp_keepalive == tcp_keepalive) {
3105+
RETURN_TRUE;
3106+
}
3107+
if(redis_sock->stream) {
3108+
/* set TCP_KEEPALIVE */
3109+
sock = (php_netstream_data_t*)redis_sock->stream->abstract;
3110+
if (setsockopt(sock->socket, SOL_SOCKET, SO_KEEPALIVE, (const void*) &tcp_keepalive,
3111+
sizeof(int)) == -1) {
3112+
RETURN_FALSE;
3113+
}
3114+
redis_sock->tcp_keepalive = tcp_keepalive;
3115+
}
3116+
RETURN_TRUE;
30893117
case REDIS_OPT_SCAN:
30903118
val_long = atol(val_str);
30913119
if(val_long==REDIS_SCAN_NORETRY || val_long==REDIS_SCAN_RETRY) {

0 commit comments

Comments
 (0)