From 73ea10e0646c8ad4990b16fdf04474e7effb6f84 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 6 Nov 2015 20:51:08 +0000 Subject: [PATCH] Add busy handler for fuzzy backend to sync workers --- src/libserver/fuzzy_backend.c | 13 +++++++++++++ src/libutil/util.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/src/libserver/fuzzy_backend.c b/src/libserver/fuzzy_backend.c index 23c4d6c64..d34617521 100644 --- a/src/libserver/fuzzy_backend.c +++ b/src/libserver/fuzzy_backend.c @@ -37,6 +37,9 @@ struct rspamd_fuzzy_backend { rspamd_mempool_t *pool; }; +static const gdouble sql_sleep_time = 0.1; +static const guint max_retries = 10; + #define msg_err_fuzzy_backend(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \ backend->pool->tag.tagname, backend->pool->tag.uid, \ G_STRFUNC, \ @@ -244,6 +247,8 @@ rspamd_fuzzy_backend_run_stmt (struct rspamd_fuzzy_backend *backend, int idx, .. sqlite3_stmt *stmt; int i; const char *argtypes; + guint retries = 0; + struct timespec ts; if (idx < 0 || idx >= RSPAMD_FUZZY_BACKEND_MAX) { @@ -288,12 +293,20 @@ rspamd_fuzzy_backend_run_stmt (struct rspamd_fuzzy_backend *backend, int idx, .. } va_end (ap); + +retry: retcode = sqlite3_step (stmt); if (retcode == prepared_stmts[idx].result) { return SQLITE_OK; } else if (retcode != SQLITE_DONE) { + if (retcode == SQLITE_BUSY && retries++ < max_retries) { + double_to_ts (sql_sleep_time, &ts); + nanosleep (&ts, NULL); + goto retry; + } + msg_debug_fuzzy_backend ("failed to execute query %s: %d, %s", prepared_stmts[idx].sql, retcode, sqlite3_errmsg (backend->db)); } diff --git a/src/libutil/util.h b/src/libutil/util.h index 06240e19b..31e68a80a 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -192,6 +192,9 @@ void g_queue_clear (GQueue *queue); #define double_to_tv(dbl, tv) do { (tv)->tv_sec = (int)(dbl); (tv)->tv_usec = \ ((dbl) - (int)(dbl)) * 1000 * 1000; \ } while (0) +#define double_to_ts(dbl, ts) do { (ts)->tv_sec = (int)(dbl); (ts)->tv_nsec = \ + ((dbl) - (int)(dbl)) * 1e9; \ +} while (0) #define tv_to_msec(tv) ((tv)->tv_sec * 1000LLU + (tv)->tv_usec / 1000LLU) #define tv_to_double(tv) ((tv)->tv_sec + (tv)->tv_usec / 1e6f) #define ts_to_usec(ts) ((ts)->tv_sec * 1000000LLU + \ -- 2.39.5