@@ -432,6 +432,9 @@ struct rspamd_config { | |||
guint words_decay; /**< limit for words for starting adaptive ignoring */ | |||
guint history_rows; /**< number of history rows stored */ | |||
guint max_sessions_cache; /**< maximum number of sessions cache elts */ | |||
guint lua_gc_step; /**< lua gc step */ | |||
guint lua_gc_pause; /**< lua gc pause */ | |||
guint full_gc_iters; /**< iterations between full gc cycle */ | |||
GList *classify_headers; /**< list of headers using for statistics */ | |||
struct module_s **compiled_modules; /**< list of compiled C modules */ |
@@ -2127,6 +2127,24 @@ rspamd_rcl_config_init (struct rspamd_config *cfg, GHashTable *skip_sections) | |||
G_STRUCT_OFFSET (struct rspamd_config, task_timeout), | |||
RSPAMD_CL_FLAG_TIME_FLOAT, | |||
"Maximum time for checking a message (alias for task_timeout)"); | |||
rspamd_rcl_add_default_handler (sub, | |||
"lua_gc_step", | |||
rspamd_rcl_parse_struct_integer, | |||
G_STRUCT_OFFSET (struct rspamd_config, lua_gc_step), | |||
RSPAMD_CL_FLAG_UINT, | |||
"Lua garbage-collector step (default: 200)"); | |||
rspamd_rcl_add_default_handler (sub, | |||
"lua_gc_pause", | |||
rspamd_rcl_parse_struct_integer, | |||
G_STRUCT_OFFSET (struct rspamd_config, lua_gc_pause), | |||
RSPAMD_CL_FLAG_UINT, | |||
"Lua garbage-collector pause (default: 200)"); | |||
rspamd_rcl_add_default_handler (sub, | |||
"full_gc_iters", | |||
rspamd_rcl_parse_struct_integer, | |||
G_STRUCT_OFFSET (struct rspamd_config, full_gc_iters), | |||
RSPAMD_CL_FLAG_UINT, | |||
"Task scanned before memory gc is performed (default: 0 - disabled)"); | |||
/* Neighbours configuration */ | |||
rspamd_rcl_add_section_doc (&sub->subsections, "neighbours", "name", |
@@ -49,6 +49,9 @@ | |||
#define DEFAULT_MAX_WORKERS 4 | |||
/* Timeout for task processing */ | |||
#define DEFAULT_TASK_TIMEOUT 8.0 | |||
#define DEFAULT_LUA_GC_STEP 200 | |||
#define DEFAULT_LUA_GC_PAUSE 200 | |||
#define DEFAULT_GC_MAXITERS 0 | |||
struct rspamd_ucl_map_cbdata { | |||
struct rspamd_config *cfg; | |||
@@ -200,6 +203,11 @@ rspamd_config_new (enum rspamd_config_init_flags flags) | |||
cfg->min_word_len = DEFAULT_MIN_WORD; | |||
cfg->max_word_len = DEFAULT_MAX_WORD; | |||
/* GC limits */ | |||
cfg->lua_gc_pause = DEFAULT_LUA_GC_PAUSE; | |||
cfg->lua_gc_step = DEFAULT_LUA_GC_STEP; | |||
cfg->full_gc_iters = DEFAULT_GC_MAXITERS; | |||
if (!(flags & RSPAMD_CONFIG_INIT_SKIP_LUA)) { | |||
cfg->lua_state = rspamd_lua_init (flags & RSPAMD_CONFIG_INIT_WIPE_LUA_MEM); | |||
cfg->own_lua_state = TRUE; |
@@ -242,7 +242,6 @@ rspamd_task_free (struct rspamd_task *task) | |||
struct rspamd_email_address *addr; | |||
struct rspamd_lua_cached_entry *entry; | |||
static guint free_iters = 0; | |||
const guint free_iters_limit = 5000; | |||
GHashTableIter it; | |||
gpointer k, v; | |||
guint i; | |||
@@ -351,7 +350,7 @@ rspamd_task_free (struct rspamd_task *task) | |||
g_hash_table_unref (task->lua_cache); | |||
} | |||
if (++free_iters > free_iters_limit) { | |||
if (task->cfg->full_gc_iters && (++free_iters > task->cfg->full_gc_iters)) { | |||
/* Perform more expensive cleanup cycle */ | |||
gsize allocated = 0, active = 0, metadata = 0, | |||
resident = 0, mapped = 0, old_lua_mem = 0; | |||
@@ -381,7 +380,8 @@ rspamd_task_free (struct rspamd_task *task) | |||
allocated, active, metadata, resident, mapped, | |||
old_lua_mem, lua_gc (task->cfg->lua_state, LUA_GCCOUNT, 0), | |||
(t2 - t1) * 1000.0); | |||
free_iters = rspamd_time_jitter (0, (gdouble)free_iters_limit / 2); | |||
free_iters = rspamd_time_jitter (0, | |||
(gdouble)task->cfg->full_gc_iters / 2); | |||
} | |||
REF_RELEASE (task->cfg); |
@@ -137,4 +137,6 @@ rspamd_lua_post_load_config (struct rspamd_config *cfg) | |||
} | |||
lua_settop (L, 0); | |||
rspamd_lua_start_gc (cfg); | |||
} |
@@ -995,13 +995,20 @@ rspamd_lua_init (bool wipe_mem) | |||
lua_setglobal (L, "get_traces"); | |||
#endif | |||
return L; | |||
} | |||
void | |||
rspamd_lua_start_gc (struct rspamd_config *cfg) | |||
{ | |||
lua_State *L = (lua_State *)cfg->lua_state; | |||
lua_settop (L, 0); | |||
/* Set up GC */ | |||
lua_gc (L, LUA_GCCOLLECT, 0); | |||
lua_gc (L, LUA_GCSETSTEPMUL, 50); | |||
lua_gc (L, LUA_GCSETPAUSE, 400); | |||
lua_gc (L, LUA_GCSETSTEPMUL, cfg->lua_gc_step); | |||
lua_gc (L, LUA_GCSETPAUSE, cfg->lua_gc_pause); | |||
lua_gc (L, LUA_GCRESTART, 0); | |||
return L; | |||
} | |||
/** |
@@ -167,7 +167,7 @@ gpointer rspamd_lua_check_class (lua_State *L, gint index, const gchar *name); | |||
*/ | |||
lua_State *rspamd_lua_init (bool wipe_mem); | |||
void rspamd_lua_start_gc (struct rspamd_config *cfg); | |||
/** | |||
* Sets field in a global variable | |||
* @param L |
@@ -498,6 +498,7 @@ main (gint argc, gchar **argv, gchar **env) | |||
lua_setglobal (L, "rspamadm"); | |||
rspamadm_fill_lua_commands (L, all_commands); | |||
rspamd_lua_start_gc (cfg); | |||
g_ptr_array_sort (all_commands, rspamdadm_commands_sort_func); | |||
g_strfreev (nargv); |
@@ -66,6 +66,7 @@ rspamd_lua_test_func (void) | |||
rspamd_lua_set_env (L, NULL, NULL, NULL); | |||
rspamd_lua_set_globals (rspamd_main->cfg, L); | |||
rspamd_lua_start_gc (rspamd_main->cfg); | |||
if (lua_test_case) { | |||
lua_pushstring (L, lua_test_case); |