GPtrArray *prefilters;
GPtrArray *postfilters;
GPtrArray *composites;
+ GPtrArray *idempotent;
GList *delayed_deps;
GList *delayed_conditions;
rspamd_mempool_t *static_pool;
RSPAMD_CACHE_PASS_WAIT_FILTERS,
RSPAMD_CACHE_PASS_POSTFILTERS,
RSPAMD_CACHE_PASS_WAIT_POSTFILTERS,
+ RSPAMD_CACHE_PASS_IDEMPOTENT,
+ RSPAMD_CACHE_PASS_WAIT_IDEMPOTENT,
RSPAMD_CACHE_PASS_DONE,
};
it = g_ptr_array_index (cache->items_by_id, i);
total_hits += it->st->total_hits;
- if (!(it->type & (SYMBOL_TYPE_PREFILTER|SYMBOL_TYPE_POSTFILTER|SYMBOL_TYPE_COMPOSITE))) {
+ if (!(it->type & (SYMBOL_TYPE_PREFILTER|
+ SYMBOL_TYPE_POSTFILTER|
+ SYMBOL_TYPE_COMPOSITE))) {
g_ptr_array_add (ord->d, it);
}
}
g_ptr_array_sort_with_data (cache->prefilters, prefilters_cmp, cache);
g_ptr_array_sort_with_data (cache->postfilters, postfilters_cmp, cache);
+ g_ptr_array_sort_with_data (cache->idempotent, postfilters_cmp, cache);
}
static gboolean
}
if (type & (SYMBOL_TYPE_CLASSIFIER|SYMBOL_TYPE_CALLBACK|
- SYMBOL_TYPE_PREFILTER|SYMBOL_TYPE_POSTFILTER)) {
+ SYMBOL_TYPE_PREFILTER|SYMBOL_TYPE_POSTFILTER|
+ SYMBOL_TYPE_IDEMPOTENT)) {
type |= SYMBOL_TYPE_NOSTAT;
}
if (item->type & SYMBOL_TYPE_PREFILTER) {
g_ptr_array_add (cache->prefilters, item);
}
+ else if (item->type & SYMBOL_TYPE_IDEMPOTENT) {
+ g_ptr_array_add (cache->idempotent, item);
+ }
else if (item->type & SYMBOL_TYPE_POSTFILTER) {
g_ptr_array_add (cache->postfilters, item);
}
g_ptr_array_free (cache->items_by_id, TRUE);
g_ptr_array_free (cache->prefilters, TRUE);
g_ptr_array_free (cache->postfilters, TRUE);
+ g_ptr_array_free (cache->idempotent, TRUE);
g_ptr_array_free (cache->composites, TRUE);
REF_RELEASE (cache->items_by_order);
cache->items_by_id = g_ptr_array_new ();
cache->prefilters = g_ptr_array_new ();
cache->postfilters = g_ptr_array_new ();
+ cache->idempotent = g_ptr_array_new ();
cache->composites = g_ptr_array_new ();
cache->mtx = rspamd_mempool_get_mutex (cache->static_pool);
cache->reload_time = cfg->cache_reload_time;
guint nitems;
nitems = cache->items_by_id->len - cache->postfilters->len -
- cache->prefilters->len - cache->composites->len;
+ cache->prefilters->len - cache->composites->len -
+ cache->idempotent->len;
if (nitems != cache->items_by_order->d->len) {
/*
}
}
+ if (all_done) {
+ checkpoint->pass = RSPAMD_CACHE_PASS_IDEMPOTENT;
+
+ return TRUE;
+ }
+
+ if (checkpoint->waitq->len == 0 ||
+ stage == RSPAMD_TASK_STAGE_IDEMPOTENT) {
+ checkpoint->pass = RSPAMD_CACHE_PASS_IDEMPOTENT;
+ }
+
+ if (stage == RSPAMD_TASK_STAGE_IDEMPOTENT) {
+ return rspamd_symbols_cache_process_symbols (task, cache, stage);
+ }
+
+ break;
+
+ case RSPAMD_CACHE_PASS_IDEMPOTENT:
+ /* Check for postfilters */
+ saved_priority = G_MININT;
+
+ for (i = 0; i < (gint)cache->idempotent->len; i ++) {
+ item = g_ptr_array_index (cache->idempotent, i);
+
+ if (!isset (checkpoint->processed_bits, item->id * 2) &&
+ !isset (checkpoint->processed_bits, item->id * 2 + 1)) {
+ /* Check priorities */
+ if (saved_priority == G_MININT) {
+ saved_priority = item->priority;
+ }
+ else {
+ if (item->priority > saved_priority &&
+ rspamd_session_events_pending (task->s) > start_events_pending) {
+ /*
+ * Delay further checks as we have higher
+ * priority filters to be processed
+ */
+ checkpoint->pass = RSPAMD_CACHE_PASS_IDEMPOTENT;
+ return TRUE;
+ }
+ }
+ rspamd_symbols_cache_check_symbol (task, cache, item,
+ checkpoint, &total_microseconds);
+ }
+ }
+ checkpoint->pass = RSPAMD_CACHE_PASS_WAIT_IDEMPOTENT;
+ break;
+
+ case RSPAMD_CACHE_PASS_WAIT_IDEMPOTENT:
+ all_done = TRUE;
+
+ for (i = 0; i < (gint)cache->idempotent->len; i ++) {
+ item = g_ptr_array_index (cache->idempotent, i);
+
+ if (!isset (checkpoint->processed_bits, item->id * 2 + 1)) {
+ all_done = FALSE;
+ break;
+ }
+ }
+
if (all_done) {
checkpoint->pass = RSPAMD_CACHE_PASS_DONE;
RSPAMD_TASK_STAGE_LEARN_PRE = (1 << 10),
RSPAMD_TASK_STAGE_LEARN = (1 << 11),
RSPAMD_TASK_STAGE_LEARN_POST = (1 << 12),
- RSPAMD_TASK_STAGE_DONE = (1 << 13),
- RSPAMD_TASK_STAGE_REPLIED = (1 << 14)
+ RSPAMD_TASK_STAGE_IDEMPOTENT = (1 << 13),
+ RSPAMD_TASK_STAGE_DONE = (1 << 14),
+ RSPAMD_TASK_STAGE_REPLIED = (1 << 15)
};
#define RSPAMD_TASK_PROCESS_ALL (RSPAMD_TASK_STAGE_CONNECT | \
RSPAMD_TASK_STAGE_LEARN_PRE | \
RSPAMD_TASK_STAGE_LEARN | \
RSPAMD_TASK_STAGE_LEARN_POST | \
+ RSPAMD_TASK_STAGE_IDEMPOTENT | \
RSPAMD_TASK_STAGE_DONE)
#define RSPAMD_TASK_PROCESS_LEARN (RSPAMD_TASK_STAGE_CONNECT | \
RSPAMD_TASK_STAGE_ENVELOPE | \