diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-09-23 13:26:02 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-09-23 13:26:02 +0100 |
commit | fbcad3a82764ea352d27a3f80183fbcc18afc199 (patch) | |
tree | db538ed2c0ddb04778a63082471757d2f4b7df80 /src/libstat | |
parent | 9d7cc9693c2d25b99ab1035c7f5c77e30d32dfd3 (diff) | |
download | rspamd-fbcad3a82764ea352d27a3f80183fbcc18afc199.tar.gz rspamd-fbcad3a82764ea352d27a3f80183fbcc18afc199.zip |
[Fix] Try to use on_connect/on_disconnect callbacks to handle internal Redis failures
Diffstat (limited to 'src/libstat')
-rw-r--r-- | src/libstat/backends/redis_backend.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libstat/backends/redis_backend.c b/src/libstat/backends/redis_backend.c index 4136ab092..2fd69f436 100644 --- a/src/libstat/backends/redis_backend.c +++ b/src/libstat/backends/redis_backend.c @@ -1614,6 +1614,39 @@ rspamd_redis_init (struct rspamd_stat_ctx *ctx, return (gpointer)backend; } +/* + * This callback is called when Redis is disconnected somehow, and the structure + * itself is usually freed by hiredis itself + */ +static void +rspamd_stat_redis_on_disconnect(const struct redisAsyncContext *ac, int status) +{ + struct redis_stat_runtime *rt = (struct redis_stat_runtime *)ac->data; + + if (ev_can_stop (&rt->timeout_event)) { + ev_timer_stop (rt->task->event_loop, &rt->timeout_event); + } + rt->redis = NULL; +} + +static void +rspamd_stat_redis_on_connect(const struct redisAsyncContext *ac, int status) +{ + struct redis_stat_runtime *rt = (struct redis_stat_runtime *)ac->data; + + + if (status == REDIS_ERR) { + /* + * We also need to reset rt->redis as it will be subsequently freed without + * calling for redis_on_disconnect callback... + */ + if (ev_can_stop (&rt->timeout_event)) { + ev_timer_stop (rt->task->event_loop, &rt->timeout_event); + } + rt->redis = NULL; + } +} + gpointer rspamd_redis_runtime (struct rspamd_task *task, struct rspamd_statfile_config *stcf, @@ -1706,6 +1739,9 @@ rspamd_redis_runtime (struct rspamd_task *task, redisLibevAttach (task->event_loop, rt->redis); rspamd_redis_maybe_auth (ctx, rt->redis); + rt->redis->data = rt; + redisAsyncSetDisconnectCallback (rt->redis, rspamd_stat_redis_on_disconnect); + redisAsyncSetConnectCallback (rt->redis, rspamd_stat_redis_on_connect); rspamd_mempool_add_destructor (task->task_pool, rspamd_redis_fin, rt); |