- 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 */
const char* server_path; /* server's unix path, 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 */
};
@ -88,10 +89,10 @@ redis_connect(const struct redis_moddata* moddata)
if(moddata->server_path && moddata->server_path[0]!=0) {
ctx = redisConnectUnixWithTimeout(moddata->server_path,
moddata->timeout);
moddata->connect_timeout);
} else {
ctx = redisConnectWithTimeout(moddata->server_host,
moddata->server_port, moddata->timeout);
moddata->server_port, moddata->connect_timeout);
}
if(!ctx || ctx->err) {
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);
goto fail;
}
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
if(redisSetTimeout(ctx, moddata->command_timeout) != REDIS_OK) {
log_err("failed to set redis timeout");
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_path = env->cfg->redis_server_path;
moddata->server_password = env->cfg->redis_server_password;
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
moddata->command_timeout.tv_sec = env->cfg->redis_timeout / 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;
for(i = 0; i < moddata->numctxs; i++) {
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
- Merge #1140: Fix spelling mistake in comments.

View File

@ -1301,6 +1301,10 @@ remote-control:
# # redis-server-password: ""
# # timeout (in ms) for communication with the redis server
# 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
# redis-expire-records: no
# # 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.
This option defaults to 100 milliseconds.
.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>
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

View File

@ -399,6 +399,8 @@ config_create(void)
cfg->redis_server_path = NULL;
cfg->redis_server_password = NULL;
cfg->redis_timeout = 100;
cfg->redis_command_timeout = 0;
cfg->redis_connect_timeout = 0;
cfg->redis_server_port = 6379;
cfg->redis_expire_records = 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-password", redis_server_password)
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_DEC(opt, "redis-logical-db", redis_logical_db)
#endif /* USE_REDIS */

View File

@ -739,6 +739,10 @@ struct config_file {
char* redis_server_password;
/** timeout (in ms) for communication with the redis server */
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 */
int redis_expire_records;
/** 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-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) }
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-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) }
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_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD
%token VAR_CACHEDB_REDISLOGICALDB
%token VAR_CACHEDB_REDISCOMMANDTIMEOUT VAR_CACHEDB_REDISCONNECTTIMEOUT
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
%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
@ -3838,7 +3839,8 @@ contents_cachedb: contents_cachedb content_cachedb
content_cachedb: cachedb_backend_name | cachedb_secret_seed |
redis_server_host | redis_server_port | redis_timeout |
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
{
@ -3954,6 +3956,32 @@ redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG
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
{
#if defined(USE_CACHEDB) && defined(USE_REDIS)