gboolean (*process_tokens)(struct rspamd_task *task, GPtrArray *tokens,
gint id,
gpointer ctx);
- void (*finalize_process)(struct rspamd_task *task,
+ gboolean (*finalize_process)(struct rspamd_task *task,
gpointer runtime, gpointer ctx);
gboolean (*learn_tokens)(struct rspamd_task *task, GPtrArray *tokens,
gint id,
gpointer ctx);
gulong (*total_learns)(struct rspamd_task *task,
gpointer runtime, gpointer ctx);
- void (*finalize_learn)(struct rspamd_task *task,
- gpointer runtime, gpointer ctx);
+ gboolean (*finalize_learn)(struct rspamd_task *task,
+ gpointer runtime, gpointer ctx, GError **err);
gulong (*inc_learns)(struct rspamd_task *task,
gpointer runtime, gpointer ctx);
gulong (*dec_learns)(struct rspamd_task *task,
gboolean rspamd_##name##_process_tokens (struct rspamd_task *task, \
GPtrArray *tokens, gint id, \
gpointer ctx); \
- void rspamd_##name##_finalize_process (struct rspamd_task *task, \
+ gboolean rspamd_##name##_finalize_process (struct rspamd_task *task, \
gpointer runtime, \
gpointer ctx); \
gboolean rspamd_##name##_learn_tokens (struct rspamd_task *task, \
GPtrArray *tokens, gint id, \
gpointer ctx); \
- void rspamd_##name##_finalize_learn (struct rspamd_task *task, \
+ gboolean rspamd_##name##_finalize_learn (struct rspamd_task *task, \
gpointer runtime, \
- gpointer ctx); \
+ gpointer ctx, GError **err); \
gulong rspamd_##name##_total_learns (struct rspamd_task *task, \
gpointer runtime, \
gpointer ctx); \
return res;
}
-void
+gboolean
rspamd_mmaped_file_finalize_learn (struct rspamd_task *task, gpointer runtime,
- gpointer ctx)
+ gpointer ctx, GError **err)
{
rspamd_mmaped_file_t *mf = (rspamd_mmaped_file_t *)runtime;
if (mf != NULL) {
msync (mf->map, mf->len, MS_INVALIDATE | MS_ASYNC);
}
+
+ return TRUE;
}
-void
+gboolean
rspamd_mmaped_file_finalize_process (struct rspamd_task *task, gpointer runtime,
gpointer ctx)
{
+ return TRUE;
}
gpointer
guint64 learned;
gint id;
gboolean has_event;
+ GError *err;
};
/* Used to get statistics from redis */
/* This calls for all callbacks pending */
redisAsyncFree (redis);
}
+
+ if (rt->err) {
+ g_error_free (rt->err);
+ rt->err = NULL;
+ }
}
static void
/* This calls for all callbacks pending */
redisAsyncFree (redis);
}
+
+ if (rt->err) {
+ g_error_free (rt->err);
+ rt->err = NULL;
+ }
}
static void
/* This calls for all callbacks pending */
redisAsyncFree (redis);
}
+
+ g_set_error (&rt->err, rspamd_redis_stat_quark (), ETIMEDOUT,
+ "error getting reply from redis server %s: timeout",
+ rspamd_upstream_name (rt->selected));
}
/* Called when we have connected to the redis server and got stats */
msg_err_task ("error getting reply from redis server %s: %s",
rspamd_upstream_name (rt->selected), c->errstr);
rspamd_upstream_fail (rt->selected);
+
+ g_set_error (&rt->err, rspamd_redis_stat_quark (), c->err,
+ "error getting reply from redis server %s: %s",
+ rspamd_upstream_name (rt->selected), c->errstr);
}
}
if (rt->redis) {
rspamd_upstream_fail (rt->selected);
}
+ g_set_error (&rt->err, rspamd_redis_stat_quark (), c->err,
+ "cannot get values: error getting reply from redis server %s: %s",
+ rspamd_upstream_name (rt->selected), c->errstr);
}
if (rt->has_event) {
if (rt->redis) {
rspamd_upstream_fail (rt->selected);
}
+
+ g_set_error (&rt->err, rspamd_redis_stat_quark (), c->err,
+ "cannot get learned: error getting reply from redis server %s: %s",
+ rspamd_upstream_name (rt->selected), c->errstr);
}
if (rt->has_event) {
return FALSE;
}
-void
+gboolean
rspamd_redis_finalize_process (struct rspamd_task *task, gpointer runtime,
gpointer ctx)
{
rt->redis = NULL;
redisAsyncFree (redis);
}
+
+ if (rt->err) {
+ g_error_free (rt->err);
+ rt->err = NULL;
+
+ return FALSE;
+ }
+
+ return TRUE;
}
gboolean
}
-void
+gboolean
rspamd_redis_finalize_learn (struct rspamd_task *task, gpointer runtime,
- gpointer ctx)
+ gpointer ctx, GError **err)
{
struct redis_stat_runtime *rt = REDIS_RUNTIME (runtime);
redisAsyncContext *redis;
rt->redis = NULL;
redisAsyncFree (redis);
}
+
+ if (rt->err) {
+ g_propagate_error (err, rt->err);
+ rt->err = NULL;
+
+ return FALSE;
+ }
+
+ return TRUE;
}
gulong
return TRUE;
}
-void
+gboolean
rspamd_sqlite3_finalize_process (struct rspamd_task *task, gpointer runtime,
gpointer ctx)
{
rt->lang_id = -1;
rt->user_id = -1;
- return;
+ return TRUE;
}
gboolean
return TRUE;
}
-void
+gboolean
rspamd_sqlite3_finalize_learn (struct rspamd_task *task, gpointer runtime,
- gpointer ctx)
+ gpointer ctx, GError **err)
{
struct rspamd_stat_sqlite3_rt *rt = runtime;
struct rspamd_stat_sqlite3_db *bk;
&wal_checkpointed) != SQLITE_OK) {
msg_warn_task ("cannot commit checkpoint: %s",
sqlite3_errmsg (bk->sqlite));
+
+ g_set_error (err, rspamd_sqlite3_backend_quark (), 500,
+ "cannot commit checkpoint: %s",
+ sqlite3_errmsg (bk->sqlite));
+ return FALSE;
}
#endif
+
+ return TRUE;
}
gulong
}
}
-static void
+static gboolean
rspamd_stat_backends_post_process (struct rspamd_stat_ctx *st_ctx,
struct rspamd_task *task)
{
bk_run = g_ptr_array_index (task->stat_runtimes, i);
if (bk_run != NULL) {
- st->backend->finalize_process (task, bk_run, st_ctx);
+ if (!st->backend->finalize_process (task, bk_run, st_ctx)) {
+ return FALSE;
+ }
}
}
+
+ return TRUE;
}
static void
}
else if (stage == RSPAMD_TASK_STAGE_CLASSIFIERS_POST) {
/* Process classifiers */
- rspamd_stat_backends_post_process (st_ctx, task);
- rspamd_stat_classifiers_process (st_ctx, task);
+ if (rspamd_stat_backends_post_process (st_ctx, task)) {
+ rspamd_stat_classifiers_process (st_ctx, task);
+ }
+ /* Do not process classifiers on backend failures */
}
task->processed_stages |= stage;
static gboolean
rspamd_stat_backends_post_learn (struct rspamd_stat_ctx *st_ctx,
struct rspamd_task *task,
- const gchar *classifier,
- gboolean spam)
+ const gchar *classifier,
+ gboolean spam,
+ GError **err)
{
struct rspamd_classifier *cl;
struct rspamd_statfile *st;
continue;
}
- if (cl->cache) {
- cache_run = cl->cache->runtime (task, cl->cachecf, TRUE);
- cl->cache->learn (task, spam, cache_run);
- }
-
if (cl->cfg->flags & RSPAMD_FLAG_CLASSIFIER_NO_BACKEND) {
res = TRUE;
continue;
continue;
}
- st->backend->finalize_learn (task, bk_run, st_ctx);
+ if (!st->backend->finalize_learn (task, bk_run, st_ctx, err)) {
+ return RSPAMD_STAT_PROCESS_ERROR;
+ }
+ }
+
+ if (cl->cache) {
+ cache_run = cl->cache->runtime (task, cl->cachecf, TRUE);
+ cl->cache->learn (task, spam, cache_run);
}
}
}
}
else if (stage == RSPAMD_TASK_STAGE_LEARN_POST) {
- if (!rspamd_stat_backends_post_learn (st_ctx, task, classifier, spam)) {
+ if (!rspamd_stat_backends_post_learn (st_ctx, task, classifier, spam, err)) {
return RSPAMD_STAT_PROCESS_ERROR;
}
}