From: Vsevolod Stakhov Date: Fri, 26 Sep 2025 15:18:28 +0000 (+0100) Subject: [Fix] Learn cache fix X-Git-Tag: 3.13.1~9^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2baa5c62e80c9bae171a4a6762ae7318ef3b57d;p=thirdparty%2Frspamd.git [Fix] Learn cache fix --- diff --git a/src/libstat/stat_process.c b/src/libstat/stat_process.c index 11b31decca..9ee7865ca4 100644 --- a/src/libstat/stat_process.c +++ b/src/libstat/stat_process.c @@ -646,6 +646,25 @@ rspamd_stat_cache_check(struct rspamd_stat_ctx *st_ctx, } learn_res = cl->cache->check(task, cache_spam, rt); + + /* Honor flags set by cache check callback (e.g. Redis) */ + if (task->flags & RSPAMD_TASK_FLAG_ALREADY_LEARNED) { + const char *already_class = rspamd_task_get_autolearn_class(task); + if (!already_class) { + already_class = cache_spam ? "spam" : "ham"; + } + + g_set_error(err, rspamd_stat_quark(), 404, "<%s> has been already " + "learned as %s, ignore it", + MESSAGE_FIELD(task, message_id), + already_class); + + return FALSE; + } + else if (task->flags & RSPAMD_TASK_FLAG_UNLEARN) { + /* Will be handled on learn stage */ + break; + } } if (learn_res == RSPAMD_LEARN_IGNORE) { @@ -1212,6 +1231,8 @@ rspamd_stat_learn_class(struct rspamd_task *task, } if (stage == RSPAMD_TASK_STAGE_LEARN_PRE) { + /* Ensure cache comparison uses the exact class we are about to learn */ + rspamd_task_set_autolearn_class(task, class_name); /* Process classifiers - determine spam boolean for compatibility */ gboolean spam = (strcmp(class_name, "spam") == 0 || strcmp(class_name, "S") == 0); rspamd_stat_preprocess(st_ctx, task, TRUE, spam); @@ -1297,6 +1318,8 @@ rspamd_stat_learn(struct rspamd_task *task, } if (stage == RSPAMD_TASK_STAGE_LEARN_PRE) { + /* Ensure cache comparison uses the exact class we are about to learn */ + rspamd_task_set_autolearn_class(task, spam ? "spam" : "ham"); /* Process classifiers */ rspamd_stat_preprocess(st_ctx, task, TRUE, spam);