- Add redis-command-timeout: 20 and redis-connect-timeout: 200,

that can set the timeout separately for commands and the
  connection set up to the redis server. If they are not
  specified, the redis-timeout value is used.
This commit is contained in:
W.C.A. Wijngaards 2024-09-17 13:10:34 +02:00
parent 606e262fdd
commit 5e9b6296b7
8 changed files with 80 additions and 7 deletions

View File

@ -58,7 +58,8 @@ struct redis_moddata {
int server_port; /* server's TCP port */ int server_port; /* server's TCP port */
const char* server_path; /* server's unix path, or "", NULL if unused */ const char* server_path; /* server's unix path, or "", NULL if unused */
const char* server_password; /* server's AUTH password, or "", NULL if unused */ const char* server_password; /* server's AUTH password, or "", NULL if unused */
struct timeval timeout; /* timeout for connection setup and commands */ struct timeval command_timeout; /* timeout for commands */
struct timeval connect_timeout; /* timeout for connect */
int logical_db; /* the redis logical database to use */ int logical_db; /* the redis logical database to use */
}; };
@ -88,10 +89,10 @@ redis_connect(const struct redis_moddata* moddata)
if(moddata->server_path && moddata->server_path[0]!=0) { if(moddata->server_path && moddata->server_path[0]!=0) {
ctx = redisConnectUnixWithTimeout(moddata->server_path, ctx = redisConnectUnixWithTimeout(moddata->server_path,
moddata->timeout); moddata->connect_timeout);
} else { } else {
ctx = redisConnectWithTimeout(moddata->server_host, ctx = redisConnectWithTimeout(moddata->server_host,
moddata->server_port, moddata->timeout); moddata->server_port, moddata->connect_timeout);
} }
if(!ctx || ctx->err) { if(!ctx || ctx->err) {
const char *errstr = "out of memory"; const char *errstr = "out of memory";
@ -100,7 +101,7 @@ redis_connect(const struct redis_moddata* moddata)
log_err("failed to connect to redis server: %s", errstr); log_err("failed to connect to redis server: %s", errstr);
goto fail; goto fail;
} }
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) { if(redisSetTimeout(ctx, moddata->command_timeout) != REDIS_OK) {
log_err("failed to set redis timeout"); log_err("failed to set redis timeout");
goto fail; goto fail;
} }
@ -159,8 +160,24 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
moddata->server_port = env->cfg->redis_server_port; moddata->server_port = env->cfg->redis_server_port;
moddata->server_path = env->cfg->redis_server_path; moddata->server_path = env->cfg->redis_server_path;
moddata->server_password = env->cfg->redis_server_password; moddata->server_password = env->cfg->redis_server_password;
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000; moddata->command_timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000; moddata->command_timeout.tv_usec =
(env->cfg->redis_timeout % 1000) * 1000;
moddata->connect_timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->connect_timeout.tv_usec =
(env->cfg->redis_timeout % 1000) * 1000;
if(env->cfg->redis_command_timeout != 0) {
moddata->command_timeout.tv_sec =
env->cfg->redis_command_timeout / 1000;
moddata->command_timeout.tv_usec =
(env->cfg->redis_command_timeout % 1000) * 1000;
}
if(env->cfg->redis_connect_timeout != 0) {
moddata->connect_timeout.tv_sec =
env->cfg->redis_connect_timeout / 1000;
moddata->connect_timeout.tv_usec =
(env->cfg->redis_connect_timeout % 1000) * 1000;
}
moddata->logical_db = env->cfg->redis_logical_db; moddata->logical_db = env->cfg->redis_logical_db;
for(i = 0; i < moddata->numctxs; i++) { for(i = 0; i < moddata->numctxs; i++) {
redisContext* ctx = redis_connect(moddata); redisContext* ctx = redis_connect(moddata);

View File

@ -1,3 +1,9 @@
17 September 2024: Wouter
- Add redis-command-timeout: 20 and redis-connect-timeout: 200,
that can set the timeout separately for commands and the
connection set up to the redis server. If they are not
specified, the redis-timeout value is used.
16 September 2024: Wouter 16 September 2024: Wouter
- Merge #1140: Fix spelling mistake in comments. - Merge #1140: Fix spelling mistake in comments.

View File

@ -1301,6 +1301,10 @@ remote-control:
# # redis-server-password: "" # # redis-server-password: ""
# # timeout (in ms) for communication with the redis server # # timeout (in ms) for communication with the redis server
# redis-timeout: 100 # redis-timeout: 100
# # timeout (in ms) for commands, if 0, uses redis-timeout.
# redis-command-timeout: 0
# # timeout (in ms) for connection set up, if 0, uses redis-timeout.
# redis-connect-timeout: 0
# # set timeout on redis records based on DNS response TTL # # set timeout on redis records based on DNS response TTL
# redis-expire-records: no # redis-expire-records: no
# # redis logical database to use, 0 is the default database. # # redis logical database to use, 0 is the default database.

View File

@ -2810,6 +2810,14 @@ if the Redis server does not have the requested data, and will try to
re-establish a new connection later. re-establish a new connection later.
This option defaults to 100 milliseconds. This option defaults to 100 milliseconds.
.TP .TP
.B redis-command-timeout: \fI<msec>\fR
The timeout to use for redis commands, in milliseconds. If 0, it uses the
redis\-timeout value. The default is 0.
.TP
.B redis-connect-timeout: \fI<msec>\fR
The timeout to use for redis connection set up, in milliseconds. If 0, it
uses the redis\-timeout value. The default is 0.
.TP
.B redis-expire-records: \fI<yes or no> .B redis-expire-records: \fI<yes or no>
If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis
records so that Redis can evict keys that have expired automatically. If records so that Redis can evict keys that have expired automatically. If

View File

@ -399,6 +399,8 @@ config_create(void)
cfg->redis_server_path = NULL; cfg->redis_server_path = NULL;
cfg->redis_server_password = NULL; cfg->redis_server_password = NULL;
cfg->redis_timeout = 100; cfg->redis_timeout = 100;
cfg->redis_command_timeout = 0;
cfg->redis_connect_timeout = 0;
cfg->redis_server_port = 6379; cfg->redis_server_port = 6379;
cfg->redis_expire_records = 0; cfg->redis_expire_records = 0;
cfg->redis_logical_db = 0; cfg->redis_logical_db = 0;
@ -1364,6 +1366,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "redis-server-path", redis_server_path) else O_STR(opt, "redis-server-path", redis_server_path)
else O_STR(opt, "redis-server-password", redis_server_password) else O_STR(opt, "redis-server-password", redis_server_password)
else O_DEC(opt, "redis-timeout", redis_timeout) else O_DEC(opt, "redis-timeout", redis_timeout)
else O_DEC(opt, "redis-command-timeout", redis_command_timeout)
else O_DEC(opt, "redis-connect-timeout", redis_connect_timeout)
else O_YNO(opt, "redis-expire-records", redis_expire_records) else O_YNO(opt, "redis-expire-records", redis_expire_records)
else O_DEC(opt, "redis-logical-db", redis_logical_db) else O_DEC(opt, "redis-logical-db", redis_logical_db)
#endif /* USE_REDIS */ #endif /* USE_REDIS */

View File

@ -739,6 +739,10 @@ struct config_file {
char* redis_server_password; char* redis_server_password;
/** timeout (in ms) for communication with the redis server */ /** timeout (in ms) for communication with the redis server */
int redis_timeout; int redis_timeout;
/** timeout (in ms) for redis commands */
int redis_command_timeout;
/** timeout (in ms) for redis connection set up */
int redis_connect_timeout;
/** set timeout on redis records based on DNS response ttl */ /** set timeout on redis records based on DNS response ttl */
int redis_expire_records; int redis_expire_records;
/** set the redis logical database upon connection */ /** set the redis logical database upon connection */

View File

@ -574,6 +574,8 @@ redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) } redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) }
redis-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) } redis-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) }
redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
redis-command-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISCOMMANDTIMEOUT) }
redis-connect-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISCONNECTTIMEOUT) }
redis-expire-records{COLON} { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) } redis-expire-records{COLON} { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) }
redis-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) } redis-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) }
ipset{COLON} { YDVAR(0, VAR_IPSET) } ipset{COLON} { YDVAR(0, VAR_IPSET) }

View File

@ -182,6 +182,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT %token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT
%token VAR_CACHEDB_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD %token VAR_CACHEDB_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD
%token VAR_CACHEDB_REDISLOGICALDB %token VAR_CACHEDB_REDISLOGICALDB
%token VAR_CACHEDB_REDISCOMMANDTIMEOUT VAR_CACHEDB_REDISCONNECTTIMEOUT
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM %token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
@ -3838,7 +3839,8 @@ contents_cachedb: contents_cachedb content_cachedb
content_cachedb: cachedb_backend_name | cachedb_secret_seed | content_cachedb: cachedb_backend_name | cachedb_secret_seed |
redis_server_host | redis_server_port | redis_timeout | redis_server_host | redis_server_port | redis_timeout |
redis_expire_records | redis_server_path | redis_server_password | redis_expire_records | redis_server_path | redis_server_password |
cachedb_no_store | redis_logical_db | cachedb_check_when_serve_expired cachedb_no_store | redis_logical_db | cachedb_check_when_serve_expired |
redis_command_timeout | redis_connect_timeout
; ;
cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
{ {
@ -3954,6 +3956,32 @@ redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG
free($2); free($2);
} }
; ;
redis_command_timeout: VAR_CACHEDB_REDISCOMMANDTIMEOUT STRING_ARG
{
#if defined(USE_CACHEDB) && defined(USE_REDIS)
OUTYY(("P(redis_command_timeout:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("redis command timeout value expected");
else cfg_parser->cfg->redis_command_timeout = atoi($2);
#else
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
#endif
free($2);
}
;
redis_connect_timeout: VAR_CACHEDB_REDISCONNECTTIMEOUT STRING_ARG
{
#if defined(USE_CACHEDB) && defined(USE_REDIS)
OUTYY(("P(redis_connect_timeout:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("redis connect timeout value expected");
else cfg_parser->cfg->redis_connect_timeout = atoi($2);
#else
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
#endif
free($2);
}
;
redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG
{ {
#if defined(USE_CACHEDB) && defined(USE_REDIS) #if defined(USE_CACHEDB) && defined(USE_REDIS)