feature: consume all packets and free all sessions before exit
This commit is contained in:
@@ -37,28 +37,15 @@ static const char logo_str[] =
|
||||
" \\__ \\ | |_ | __/ | | | | | (_| | | |\n"
|
||||
" |___/ \\__| \\___| |_| |_| \\__,_| |_|\n";
|
||||
|
||||
struct schedule_data
|
||||
{
|
||||
uint64_t last_free_expired_session_timestamp;
|
||||
uint64_t last_free_expired_ip_frag_timestamp;
|
||||
uint64_t last_merge_thread_stat_timestamp;
|
||||
|
||||
uint64_t free_expired_session_interval;
|
||||
uint64_t free_expired_session_batch;
|
||||
|
||||
uint64_t free_expired_ip_frag_interval;
|
||||
uint64_t free_expired_ip_frag_batch;
|
||||
|
||||
uint64_t merge_stat_interval;
|
||||
uint64_t packet_io_yield_interval;
|
||||
};
|
||||
|
||||
struct stellar_thread
|
||||
{
|
||||
pthread_t tid;
|
||||
uint16_t idx;
|
||||
uint64_t is_runing;
|
||||
struct schedule_data sched_data;
|
||||
uint64_t need_exit;
|
||||
uint64_t last_free_expired_session_timestamp;
|
||||
uint64_t last_free_expired_ip_frag_timestamp;
|
||||
uint64_t last_merge_thread_stat_timestamp;
|
||||
struct snowflake *snowflake;
|
||||
struct ip_reassembly *ip_mgr;
|
||||
struct session_manager *sess_mgr;
|
||||
@@ -202,11 +189,19 @@ static void *work_thread(void *arg)
|
||||
struct stellar_thread *thread = (struct stellar_thread *)arg;
|
||||
struct ip_reassembly *ip_reass = thread->ip_mgr;
|
||||
struct session_manager *sess_mgr = thread->sess_mgr;
|
||||
struct session_manager_stat *sess_stat = session_manager_stat(sess_mgr);
|
||||
struct stellar *st = thread->st;
|
||||
struct stellar_config *config = &st->config;
|
||||
struct stellar_runtime *runtime = &st->runtime;
|
||||
struct schedule_data *sched_data = &thread->sched_data;
|
||||
struct packet_io *packet_io = runtime->packet_io;
|
||||
struct plugin_manager_schema *plug_mgr = runtime->plug_mgr;
|
||||
uint64_t free_expired_session_interval = config->sched_opts.free_expired_session_interval;
|
||||
uint64_t free_expired_session_batch = config->sched_opts.free_expired_session_batch;
|
||||
uint64_t froce_session_expire_before_exit = config->sched_opts.froce_session_expire_before_exit;
|
||||
uint64_t free_expired_ip_frag_interval = config->sched_opts.free_expired_ip_frag_interval;
|
||||
uint64_t free_expired_ip_frag_batch = config->sched_opts.free_expired_ip_frag_batch;
|
||||
uint64_t merge_stat_interval = config->sched_opts.merge_stat_interval;
|
||||
uint64_t packet_io_yield_interval = config->sched_opts.packet_io_yield_interval;
|
||||
uint16_t thr_idx = thread->idx;
|
||||
|
||||
__current_thread_idx = thr_idx;
|
||||
@@ -232,7 +227,7 @@ static void *work_thread(void *arg)
|
||||
ATOMIC_SET(&thread->is_runing, 1);
|
||||
CORE_LOG_FATAL("worker thread %d runing", thr_idx);
|
||||
|
||||
while (ATOMIC_READ(&runtime->need_exit) == 0)
|
||||
while (ATOMIC_READ(&thread->need_exit) == 0)
|
||||
{
|
||||
/*
|
||||
* We use the system's real time instead of monotonic time for the following reasons:
|
||||
@@ -345,29 +340,43 @@ static void *work_thread(void *arg)
|
||||
plugin_manager_on_polling(plug_mgr);
|
||||
|
||||
// per free_expired_session_interval MAX free_expired_session_batch sessions are released
|
||||
if (now_ms - sched_data->last_free_expired_session_timestamp >= sched_data->free_expired_session_interval)
|
||||
if (now_ms - thread->last_free_expired_session_timestamp >= free_expired_session_interval)
|
||||
{
|
||||
free_expired_sessions(sess_mgr, sched_data->free_expired_session_batch, now_ms);
|
||||
sched_data->last_free_expired_session_timestamp = now_ms;
|
||||
free_expired_sessions(sess_mgr, free_expired_session_batch, now_ms);
|
||||
thread->last_free_expired_session_timestamp = now_ms;
|
||||
}
|
||||
|
||||
// per merge_stat_interval merge thread stat
|
||||
if (now_ms - sched_data->last_merge_thread_stat_timestamp >= sched_data->merge_stat_interval)
|
||||
if (now_ms - thread->last_merge_thread_stat_timestamp >= merge_stat_interval)
|
||||
{
|
||||
merge_thread_stat(thread);
|
||||
sched_data->last_merge_thread_stat_timestamp = now_ms;
|
||||
thread->last_merge_thread_stat_timestamp = now_ms;
|
||||
}
|
||||
|
||||
// per free_expired_ip_frag_interval MAX free_expired_ip_frag_batch ip fragments are released
|
||||
if (now_ms - sched_data->last_free_expired_ip_frag_timestamp >= sched_data->free_expired_ip_frag_interval)
|
||||
if (now_ms - thread->last_free_expired_ip_frag_timestamp >= free_expired_ip_frag_interval)
|
||||
{
|
||||
ip_reassembly_expire(ip_reass, sched_data->free_expired_ip_frag_batch, now_ms);
|
||||
sched_data->last_free_expired_ip_frag_timestamp = now_ms;
|
||||
ip_reassembly_expire(ip_reass, free_expired_ip_frag_batch, now_ms);
|
||||
thread->last_free_expired_ip_frag_timestamp = now_ms;
|
||||
}
|
||||
|
||||
if (nr_recv == 0)
|
||||
{
|
||||
packet_io_yield(packet_io, thr_idx, sched_data->packet_io_yield_interval);
|
||||
packet_io_yield(packet_io, thr_idx, packet_io_yield_interval);
|
||||
}
|
||||
}
|
||||
|
||||
if (froce_session_expire_before_exit)
|
||||
{
|
||||
free_expired_sessions(sess_mgr, UINT64_MAX, UINT64_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (sess_stat->tcp_sess_used > 0 || sess_stat->udp_sess_used > 0)
|
||||
{
|
||||
now_ms = clock_get_real_time_ms();
|
||||
free_expired_sessions(sess_mgr, free_expired_session_batch, now_ms);
|
||||
usleep(1000); // 1ms
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,27 +393,6 @@ static void *work_thread(void *arg)
|
||||
* Stellar Main Function
|
||||
******************************************************************************/
|
||||
|
||||
static int all_session_have_freed(struct stellar_runtime *runtime, struct stellar_config *config)
|
||||
{
|
||||
for (int i = 0; i < config->pkt_io_opts.nr_threads; i++)
|
||||
{
|
||||
struct session_manager *sess_mgr = runtime->threads[i].sess_mgr;
|
||||
struct session_manager_stat *sess_stat = session_manager_stat(sess_mgr);
|
||||
|
||||
if (ATOMIC_READ(&sess_stat->tcp_sess_used) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ATOMIC_READ(&sess_stat->udp_sess_used) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int stellar_thread_init(struct stellar *st)
|
||||
{
|
||||
struct stellar_runtime *runtime = &st->runtime;
|
||||
@@ -417,18 +405,9 @@ static int stellar_thread_init(struct stellar *st)
|
||||
thread->idx = i;
|
||||
thread->is_runing = 0;
|
||||
|
||||
thread->sched_data.last_free_expired_session_timestamp = now_ms;
|
||||
thread->sched_data.last_free_expired_ip_frag_timestamp = now_ms;
|
||||
thread->sched_data.last_merge_thread_stat_timestamp = now_ms;
|
||||
|
||||
thread->sched_data.free_expired_session_interval = config->sched_opts.free_expired_session_interval;
|
||||
thread->sched_data.free_expired_session_batch = config->sched_opts.free_expired_session_batch;
|
||||
|
||||
thread->sched_data.free_expired_ip_frag_interval = config->sched_opts.free_expired_ip_frag_interval;
|
||||
thread->sched_data.free_expired_ip_frag_batch = config->sched_opts.free_expired_ip_frag_batch;
|
||||
|
||||
thread->sched_data.merge_stat_interval = config->sched_opts.merge_stat_interval;
|
||||
thread->sched_data.packet_io_yield_interval = config->sched_opts.packet_io_yield_interval;
|
||||
thread->last_free_expired_session_timestamp = now_ms;
|
||||
thread->last_free_expired_ip_frag_timestamp = now_ms;
|
||||
thread->last_merge_thread_stat_timestamp = now_ms;
|
||||
|
||||
thread->snowflake = snowflake_new(i, config->snowflake_opts.snowflake_base, config->snowflake_opts.snowflake_offset);
|
||||
if (thread->snowflake == NULL)
|
||||
@@ -623,16 +602,21 @@ void stellar_run(struct stellar *st)
|
||||
}
|
||||
usleep(1000); // 1ms
|
||||
|
||||
// only available in dump file mode, automatically exits when all sessions have been released
|
||||
if (packet_io_isbreak(runtime->packet_io) && all_session_have_freed(runtime, config))
|
||||
// only available in dumpfile mode
|
||||
if (packet_io_isbreak(runtime->packet_io))
|
||||
{
|
||||
CORE_LOG_FATAL("all sessions have been released, notify threads to exit");
|
||||
for (uint16_t i = 0; i < config->pkt_io_opts.nr_threads; i++)
|
||||
{
|
||||
struct stellar_thread *thread = &runtime->threads[i];
|
||||
ATOMIC_SET(&thread->need_exit, 1);
|
||||
}
|
||||
CORE_LOG_FATAL("notify worker thread to exit");
|
||||
stellar_stat_output(runtime->stat); // flush stat
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// berfore exit, output last stat
|
||||
stellar_thread_join(st);
|
||||
stellar_stat_output(runtime->stat);
|
||||
}
|
||||
|
||||
@@ -642,7 +626,6 @@ void stellar_free(struct stellar *st)
|
||||
{
|
||||
struct stellar_runtime *runtime = &st->runtime;
|
||||
|
||||
stellar_thread_join(st);
|
||||
stellar_thread_clean(st);
|
||||
packet_io_free(runtime->packet_io);
|
||||
plugin_manager_exit(runtime->plug_mgr);
|
||||
|
||||
Reference in New Issue
Block a user