From 0a52bb55e954a56fc4d2a934e4d33ee1e77795a0 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 5 Sep 2016 16:57:40 +0100 Subject: [PATCH] [Minor] Fix multiple issues in redis fuzzy backend --- src/libserver/fuzzy_backend.c | 10 ++ src/libserver/fuzzy_backend_redis.c | 136 ++++++++++++++++++++++++++-- 2 files changed, 137 insertions(+), 9 deletions(-) diff --git a/src/libserver/fuzzy_backend.c b/src/libserver/fuzzy_backend.c index 030028389..3dec60c57 100644 --- a/src/libserver/fuzzy_backend.c +++ b/src/libserver/fuzzy_backend.c @@ -85,6 +85,16 @@ static const struct rspamd_fuzzy_backend_subr fuzzy_subrs[] = { .id = rspamd_fuzzy_backend_id_sqlite, .periodic = rspamd_fuzzy_backend_expire_sqlite, .close = rspamd_fuzzy_backend_close_sqlite, + }, + [RSPAMD_FUZZY_BACKEND_REDIS] = { + .init = rspamd_fuzzy_backend_init_redis, + .check = rspamd_fuzzy_backend_check_redis, + .update = rspamd_fuzzy_backend_update_redis, + .count = rspamd_fuzzy_backend_count_redis, + .version = rspamd_fuzzy_backend_version_redis, + .id = rspamd_fuzzy_backend_id_redis, + .periodic = rspamd_fuzzy_backend_expire_redis, + .close = rspamd_fuzzy_backend_close_redis, } }; diff --git a/src/libserver/fuzzy_backend_redis.c b/src/libserver/fuzzy_backend_redis.c index 66490d386..a03c29a6c 100644 --- a/src/libserver/fuzzy_backend_redis.c +++ b/src/libserver/fuzzy_backend_redis.c @@ -193,7 +193,7 @@ rspamd_fuzzy_backend_redis_dtor (struct rspamd_fuzzy_backend_redis *backend) rspamd_upstreams_destroy (backend->read_servers); } if (backend->write_servers) { - rspamd_upstreams_destroy (backend->read_servers); + rspamd_upstreams_destroy (backend->write_servers); } if (backend->id) { @@ -893,6 +893,7 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk, { GString *key, *value; guint cur_shift = *shift; + guint i; struct rspamd_fuzzy_cmd *cmd; if (io_cmd->is_shingle) { @@ -933,7 +934,7 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk, g_string_free (value, FALSE); if (redisAsyncCommandArgv (session->ctx, NULL, NULL, - 3, + 4, (const gchar **)&session->argv[cur_shift - 4], &session->argv_lens[cur_shift - 4]) != REDIS_OK) { @@ -957,7 +958,7 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk, g_string_free (value, FALSE); if (redisAsyncCommandArgv (session->ctx, NULL, NULL, - 3, + 4, (const gchar **)&session->argv[cur_shift - 4], &session->argv_lens[cur_shift - 4]) != REDIS_OK) { @@ -986,6 +987,121 @@ rspamd_fuzzy_update_append_command (struct rspamd_fuzzy_backend *bk, return FALSE; } + + /* INCR */ + key = g_string_new (session->backend->redis_object); + g_string_append (key, "_count"); + session->argv[cur_shift] = g_strdup ("INCR"); + session->argv_lens[cur_shift++] = sizeof ("INCR") - 1; + session->argv[cur_shift] = key->str; + session->argv_lens[cur_shift++] = key->len; + g_string_free (key, FALSE); + + if (redisAsyncCommandArgv (session->ctx, NULL, NULL, + 2, + (const gchar **)&session->argv[cur_shift - 2], + &session->argv_lens[cur_shift - 2]) != REDIS_OK) { + + return FALSE; + } + } + else if (cmd->cmd == FUZZY_DEL) { + /* DEL */ + key = g_string_new (session->backend->redis_object); + g_string_append_len (key, cmd->digest, sizeof (cmd->digest)); + session->argv[cur_shift] = g_strdup ("DEL"); + session->argv_lens[cur_shift++] = sizeof ("DEL") - 1; + session->argv[cur_shift] = key->str; + session->argv_lens[cur_shift++] = key->len; + g_string_free (key, FALSE); + + if (redisAsyncCommandArgv (session->ctx, NULL, NULL, + 2, + (const gchar **)&session->argv[cur_shift - 2], + &session->argv_lens[cur_shift - 2]) != REDIS_OK) { + + return FALSE; + } + + /* DECR */ + key = g_string_new (session->backend->redis_object); + g_string_append (key, "_count"); + session->argv[cur_shift] = g_strdup ("DECR"); + session->argv_lens[cur_shift++] = sizeof ("DECR") - 1; + session->argv[cur_shift] = key->str; + session->argv_lens[cur_shift++] = key->len; + g_string_free (key, FALSE); + + if (redisAsyncCommandArgv (session->ctx, NULL, NULL, + 2, + (const gchar **)&session->argv[cur_shift - 2], + &session->argv_lens[cur_shift - 2]) != REDIS_OK) { + + return FALSE; + } + } + + if (io_cmd->is_shingle) { + + + if (cmd->cmd == FUZZY_WRITE) { + for (i = 0; i < RSPAMD_SHINGLE_SIZE; i ++) { + guchar *hval; + /* + * For each command with shingles we additionally emit 32 commands: + * SETEX __ + */ + + /* SETEX */ + key = g_string_new (session->backend->redis_object); + rspamd_printf_gstring (key, "_%d_%uL", i, + io_cmd->cmd.shingle.sgl.hashes[i]); + value = g_string_sized_new (32); + rspamd_printf_gstring (value, "%d", + (gint)rspamd_fuzzy_backend_get_expire (bk)); + hval = g_malloc (sizeof (io_cmd->cmd.shingle.basic.digest)); + memcpy (hval, io_cmd->cmd.shingle.basic.digest, + sizeof (io_cmd->cmd.shingle.basic.digest)); + session->argv[cur_shift] = g_strdup ("SETEX"); + session->argv_lens[cur_shift++] = sizeof ("SETEX") - 1; + session->argv[cur_shift] = key->str; + session->argv_lens[cur_shift++] = key->len; + session->argv[cur_shift] = value->str; + session->argv_lens[cur_shift++] = value->len; + session->argv[cur_shift] = hval; + session->argv_lens[cur_shift++] = sizeof (io_cmd->cmd.shingle.basic.digest); + g_string_free (key, FALSE); + g_string_free (value, FALSE); + + if (redisAsyncCommandArgv (session->ctx, NULL, NULL, + 4, + (const gchar **)&session->argv[cur_shift - 4], + &session->argv_lens[cur_shift - 4]) != REDIS_OK) { + + return FALSE; + } + } + } + else if (cmd->cmd == FUZZY_DEL) { + for (i = 0; i < RSPAMD_SHINGLE_SIZE; i ++) { + key = g_string_new (session->backend->redis_object); + rspamd_printf_gstring (key, "_%d_%uL", i, + io_cmd->cmd.shingle.sgl.hashes[i]); + session->argv[cur_shift] = g_strdup ("DEL"); + session->argv_lens[cur_shift++] = sizeof ("DEL") - 1; + session->argv[cur_shift] = key->str; + session->argv_lens[cur_shift++] = key->len; + g_string_free (key, FALSE); + + if (redisAsyncCommandArgv (session->ctx, NULL, NULL, + 2, + (const gchar **)&session->argv[cur_shift - 2], + &session->argv_lens[cur_shift - 2]) != REDIS_OK) { + + return FALSE; + } + } + } } *shift = cur_shift; @@ -1055,6 +1171,7 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk, * HSET F * HINCRBY V * EXPIRE + * INCR * * Where is || * @@ -1066,10 +1183,11 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk, * * For each delete command with shingles we emit also 32 commands: * DEL __ + * DECR */ - ncommands = 3; /* For MULTI + EXEC */ - nargs = 5; + ncommands = 3; /* For MULTI + EXEC + INCR */ + nargs = 4; for (cur = updates->head; cur != NULL; cur = g_list_next (cur)) { io_cmd = cur->data; @@ -1082,8 +1200,8 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk, } if (cmd->cmd == FUZZY_WRITE) { - ncommands += 3; - nargs += 11; + ncommands += 4; + nargs += 13; if (io_cmd->is_shingle) { ncommands += RSPAMD_SHINGLE_SIZE; @@ -1092,8 +1210,8 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk, } else if (cmd->cmd == FUZZY_DEL) { - ncommands += 1; - nargs += 2; + ncommands += 2; + nargs += 4; if (io_cmd->is_shingle) { ncommands += RSPAMD_SHINGLE_SIZE; -- 2.39.5