static void jitter_timeout_event (struct rspamd_map *map, gboolean locked, gboolean initial, gboolean errored) { const gdouble error_mult = 20.0, lock_mult = 0.5; gdouble jittered_sec; gdouble timeout; if (initial) { timeout = 0.0; } else if (errored) { timeout = map->cfg->map_timeout * error_mult; } else if (locked) { timeout = map->cfg->map_timeout * lock_mult; } else { timeout = map->cfg->map_timeout; } /* Plan event again with jitter */ evtimer_del (&map->ev); jittered_sec = rspamd_time_jitter (timeout, 0); double_to_tv (jittered_sec, &map->tv); evtimer_add (&map->ev, &map->tv); }
static void rspamd_symbols_cache_resort_cb (gint fd, short what, gpointer ud) { struct timeval tv; gdouble tm; struct symbols_cache *cache = ud; struct cache_item *item, *parent; guint i; /* Plan new event */ tm = rspamd_time_jitter (cache->reload_time, 0); msg_debug_cache ("resort symbols cache, next reload in %.2f seconds", tm); g_assert (cache != NULL); evtimer_set (&cache->resort_ev, rspamd_symbols_cache_resort_cb, cache); double_to_tv (tm, &tv); event_add (&cache->resort_ev, &tv); rspamd_mempool_lock_mutex (cache->mtx); /* Gather stats from shared execution times */ for (i = 0; i < cache->items_by_id->len; i ++) { item = g_ptr_array_index (cache->items_by_id, i); if (item->type & (SYMBOL_TYPE_CALLBACK|SYMBOL_TYPE_NORMAL)) { if (item->cd->number > 0) { item->avg_counter += item->cd->number + 1; item->avg_time = item->avg_time + (item->cd->value - item->avg_time) / (gdouble)item->avg_counter; item->cd->value = item->avg_time; item->cd->number = item->avg_counter; } } } /* Sync virtual symbols */ for (i = 0; i < cache->items_by_id->len; i ++) { item = g_ptr_array_index (cache->items_by_id, i); if (item->parent != -1) { parent = g_ptr_array_index (cache->items_by_id, item->parent); if (parent) { item->avg_time = parent->avg_time; item->avg_counter = parent->avg_counter; } } } rspamd_mempool_unlock_mutex (cache->mtx); rspamd_symbols_cache_resort (cache); }
static void jitter_timeout_event (struct rspamd_map *map, gboolean locked, gboolean initial) { gdouble jittered_sec; gdouble timeout = initial ? 1.0 : map->cfg->map_timeout; /* Plan event again with jitter */ evtimer_del (&map->ev); jittered_sec = rspamd_time_jitter (locked ? timeout * 4 : timeout, 0); double_to_tv (jittered_sec, &map->tv); evtimer_add (&map->ev, &map->tv); }
void rspamd_symbols_cache_start_refresh (struct symbols_cache * cache, struct event_base *ev_base) { struct timeval tv; gdouble tm; tm = rspamd_time_jitter (cache->reload_time, 0); g_assert (cache != NULL); evtimer_set (&cache->resort_ev, rspamd_symbols_cache_resort_cb, cache); event_base_set (ev_base, &cache->resort_ev); double_to_tv (tm, &tv); event_add (&cache->resort_ev, &tv); }
static void rspamd_async_elt_on_timer (gint fd, short what, gpointer d) { struct rspamd_stat_async_elt *elt = d; gdouble jittered_time; event_del (&elt->timer_ev); if (elt->enabled) { elt->handler (elt, elt->ud); } jittered_time = rspamd_time_jitter (elt->timeout, 0); double_to_tv (jittered_time, &elt->tv); event_add (&elt->timer_ev, &elt->tv); }
static void rspamd_map_schedule_periodic (struct rspamd_map *map, gboolean locked, gboolean initial, gboolean errored) { const gdouble error_mult = 20.0, lock_mult = 0.1; gdouble jittered_sec; gdouble timeout; struct map_periodic_cbdata *cbd; timeout = map->poll_timeout; if (initial) { timeout = 0.0; } if (errored) { timeout = map->poll_timeout * error_mult; } else if (locked) { timeout = lock_mult; } cbd = g_slice_alloc0 (sizeof (*cbd)); cbd->cbdata.state = 0; cbd->cbdata.prev_data = *map->user_data; cbd->cbdata.cur_data = NULL; cbd->cbdata.map = map; cbd->map = map; REF_INIT_RETAIN (cbd, rspamd_map_periodic_dtor); if (initial) { evtimer_set (&map->ev, rspamd_map_periodic_callback, cbd); event_base_set (map->ev_base, &map->ev); } else { evtimer_del (&map->ev); evtimer_set (&map->ev, rspamd_map_periodic_callback, cbd); event_base_set (map->ev_base, &map->ev); } jittered_sec = rspamd_time_jitter (timeout, 0); msg_debug_map ("schedule new periodic event %p in %.2f seconds", cbd, jittered_sec); double_to_tv (jittered_sec, &map->tv); evtimer_add (&map->ev, &map->tv); }
void rspamd_rrd_test_func () { gchar tmpfile[PATH_MAX]; struct rrd_rra_def rra[4]; struct rrd_ds_def ds[2]; GArray ar; GError *err = NULL; struct rspamd_rrd_file *rrd; gdouble ticks; gint i; gdouble t[2], cnt = 0.0; rspamd_snprintf (tmpfile, sizeof (tmpfile), "/tmp/rspamd_rrd.rrd"); unlink (tmpfile); /* Create sample rrd */ ticks = rspamd_get_calendar_ticks (); g_assert ((rrd = rspamd_rrd_create (tmpfile, 2, 4, 1, ticks, &err)) != NULL); /* Add RRA */ rrd_make_default_rra ("AVERAGE", pdp_per_cdp, rows_cnt, &rra[0]); rrd_make_default_rra ("AVERAGE", pdp_per_cdp / 2, rows_cnt, &rra[1]); rrd_make_default_rra ("AVERAGE", pdp_per_cdp / 4, rows_cnt, &rra[2]); rrd_make_default_rra ("AVERAGE", pdp_per_cdp / 10, rows_cnt, &rra[3]); ar.data = rra; ar.len = sizeof (rra); g_assert (rspamd_rrd_add_rra (rrd, &ar, &err)); /* Add DS */ rrd_make_default_ds ("test", "COUNTER", 1, &ds[0]); rrd_make_default_ds ("test1", "COUNTER", 1, &ds[1]); ar.data = ds; ar.len = sizeof (ds); g_assert (rspamd_rrd_add_ds (rrd, &ar, &err)); /* Finalize */ g_assert (rspamd_rrd_finalize (rrd, &err)); /* Close */ rspamd_rrd_close (rrd); /* Reopen */ g_assert ((rrd = rspamd_rrd_open (tmpfile, &err)) != NULL); /* Add some points */ for (i = 0; i < pdp_per_cdp * rows_cnt / 2; i ++) { t[0] = i; t[1] = cnt ++; ar.data = t; ar.len = sizeof (t); ticks += 1.0; g_assert (rspamd_rrd_add_record (rrd, &ar, ticks, &err)); } /* Add some more points */ for (i = 0; i < pdp_per_cdp * rows_cnt / 4; i ++) { t[0] = i + rspamd_time_jitter (1.0, 0.0); t[1] = cnt ++; ar.data = t; ar.len = sizeof (t); ticks += 1.0; g_assert (rspamd_rrd_add_record (rrd, &ar, ticks, &err)); } /* Add undefined interval */ ticks += 200; /* Add some more points */ for (i = 0; i < pdp_per_cdp * rows_cnt / 8; i ++) { t[0] = i; t[1] = cnt ++; ar.data = t; ar.len = sizeof (t); ticks += 1.0; g_assert (rspamd_rrd_add_record (rrd, &ar, ticks, &err)); } /* Finish */ rspamd_rrd_close (rrd); /* unlink (tmpfile); */ }