Add session timer

This commit is contained in:
luwenpeng
2023-12-12 18:41:53 +08:00
parent 006315fb7c
commit 2d3e182b5a
11 changed files with 612 additions and 234 deletions

View File

@@ -6,11 +6,13 @@ add_library(session_manager
session.cpp
session_address.cpp
session_pool.cpp
session_table.cpp)
session_table.cpp
session_timer.cpp)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/deps/timeout)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/packet)
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/session)
target_link_libraries(session_manager)
target_link_libraries(session_manager timeout)
###############################################################################
# gtest
@@ -32,8 +34,13 @@ add_executable(gtest_session_table gtest_session_table.cpp)
target_include_directories(gtest_session_table PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(gtest_session_table session_manager gtest)
add_executable(gtest_session_timer gtest_session_timer.cpp)
target_include_directories(gtest_session_timer PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(gtest_session_timer session_manager gtest)
include(GoogleTest)
gtest_discover_tests(gtest_session)
gtest_discover_tests(gtest_session_address)
gtest_discover_tests(gtest_session_pool)
gtest_discover_tests(gtest_session_table)
gtest_discover_tests(gtest_session_table)
gtest_discover_tests(gtest_session_timer)

View File

@@ -0,0 +1,160 @@
#include <gtest/gtest.h>
#include "session_timer.h"
#include "session_private.h"
static void session_expire(struct session *sess)
{
printf("=== session %lu expired ===\n", session_get_id(sess));
}
TEST(SESSION_TIMER, ADD_DEL)
{
struct session sess;
struct session_timer *timer = session_timer_create();
EXPECT_TRUE(timer != NULL);
session_init(&sess);
session_set_id(&sess, 1);
session_set_expirecb(&sess, session_expire, 1000);
session_timer_add_session(timer, &sess);
session_timer_del_session(timer, &sess);
session_timer_destroy(timer);
}
TEST(SESSION_TIMER, EXPIRE)
{
struct session *sess = NULL;
struct session sess1;
struct session sess2;
struct session sess3;
struct session_timer *timer = session_timer_create();
EXPECT_TRUE(timer != NULL);
session_init(&sess1);
session_init(&sess2);
session_init(&sess3);
session_set_id(&sess1, 1);
session_set_id(&sess2, 2);
session_set_id(&sess3, 3);
session_set_expirecb(&sess1, session_expire, 5);
session_set_expirecb(&sess2, session_expire, 5);
session_set_expirecb(&sess3, session_expire, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
session_timer_add_session(timer, &sess3);
for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++)
{
printf("current timestamp %lu\n", abs_current_ts);
do
{
sess = session_timer_expire_session(timer, abs_current_ts);
if (sess != NULL)
{
session_run_expirecb(sess);
}
} while (sess);
}
session_timer_destroy(timer);
}
TEST(SESSION_TIMER, BEFORE_EXPIRE_DEL)
{
struct session *sess = NULL;
struct session sess1;
struct session sess2;
struct session sess3;
struct session_timer *timer = session_timer_create();
EXPECT_TRUE(timer != NULL);
session_init(&sess1);
session_init(&sess2);
session_init(&sess3);
session_set_id(&sess1, 1);
session_set_id(&sess2, 2);
session_set_id(&sess3, 3);
session_set_expirecb(&sess1, session_expire, 5);
session_set_expirecb(&sess2, session_expire, 5);
session_set_expirecb(&sess3, session_expire, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
session_timer_add_session(timer, &sess3);
for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++)
{
printf("current timestamp %lu\n", abs_current_ts);
if (abs_current_ts == 2)
{
printf("delete timer 2\n");
session_timer_del_session(timer, &sess2);
}
do
{
sess = session_timer_expire_session(timer, abs_current_ts);
if (sess != NULL)
{
session_run_expirecb(sess);
}
} while (sess);
}
session_timer_destroy(timer);
}
TEST(SESSION_TIMER, BEFORE_EXPIRE_UPDATE)
{
struct session *sess = NULL;
struct session sess1;
struct session sess2;
struct session sess3;
struct session_timer *timer = session_timer_create();
EXPECT_TRUE(timer != NULL);
session_init(&sess1);
session_init(&sess2);
session_init(&sess3);
session_set_id(&sess1, 1);
session_set_id(&sess2, 2);
session_set_id(&sess3, 3);
session_set_expirecb(&sess1, session_expire, 5);
session_set_expirecb(&sess2, session_expire, 5);
session_set_expirecb(&sess3, session_expire, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
session_timer_add_session(timer, &sess3);
for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++)
{
printf("current timestamp %lu\n", abs_current_ts);
if (abs_current_ts == 2)
{
printf("update timer 2\n");
session_timer_del_session(timer, &sess2);
session_set_expirecb(&sess2, session_expire, 8);
session_timer_add_session(timer, &sess2);
}
do
{
sess = session_timer_expire_session(timer, abs_current_ts);
if (sess != NULL)
{
session_run_expirecb(sess);
}
} while (sess);
}
session_timer_destroy(timer);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -184,11 +184,6 @@ void session_set_last_time(struct session *sess, uint64_t timestamp)
sess->last_time = timestamp;
}
void session_set_expire_time(struct session *sess, uint64_t timestamp)
{
sess->expire_time = timestamp;
}
uint64_t session_get_create_time(struct session *sess)
{
return sess->create_time;
@@ -199,11 +194,6 @@ uint64_t session_get_last_time(struct session *sess)
return sess->last_time;
}
uint64_t session_get_expire_time(struct session *sess)
{
return sess->expire_time;
}
// session event
bool session_push_event(struct session *sess, uint32_t event)
{
@@ -304,3 +294,34 @@ void session_free_ex_data(struct session *sess, uint8_t idx)
sess->ex_data[idx] = NULL;
}
/******************************************************************************
* session expire
******************************************************************************/
// session expire
void session_set_expirecb(struct session *sess, session_expire_cb fn, uint64_t abs_expire_ts)
{
struct timeout *timeout = &sess->timeout;
timeout_init(timeout, TIMEOUT_ABS);
timeout_setcb(timeout, fn, sess);
sess->abs_expire_ts = abs_expire_ts;
}
void session_del_expirecb(struct session *sess)
{
struct timeout *timeout = &sess->timeout;
timeout_init(timeout, 0);
sess->abs_expire_ts = 0;
}
void session_run_expirecb(struct session *sess)
{
struct timeout *timeout = &sess->timeout;
if (timeout->callback.fn)
{
timeout->callback.fn(timeout->callback.arg);
}
}

View File

@@ -123,6 +123,17 @@ void *session_get0_ex_data(struct session *sess, uint8_t idx);
*/
void session_free_ex_data(struct session *sess, uint8_t idx);
/******************************************************************************
* session expire
******************************************************************************/
typedef void (*session_expire_cb)(struct session *sess);
// session timer
void session_set_expirecb(struct session *sess, session_expire_cb fn, uint64_t abs_timeout_ts);
void session_del_expirecb(struct session *sess);
void session_run_expirecb(struct session *sess);
#ifdef __cpluscplus
}
#endif

View File

@@ -14,6 +14,14 @@ extern "C"
#include "session.h"
#include "session_address.h"
#define TIMEOUT_CB_OVERRIDE
struct timeout_cb
{
session_expire_cb fn;
struct session *arg;
};
#include "timeout.h"
#define EX_DATA_MAX_COUNT 128
#define SESSION_EVENT_QUEUE_SIZE 256
@@ -45,7 +53,6 @@ struct session
// session timestamp
uint64_t create_time;
uint64_t last_time;
uint64_t expire_time;
/******************************
* Session Ev Queue Zone
@@ -64,6 +71,8 @@ struct session
******************************/
// session timer
struct timeout timeout;
uint64_t abs_expire_ts;
/******************************
* Session Pool Zone

View File

@@ -0,0 +1,69 @@
#include "session_timer.h"
#include "session_private.h"
struct session_timer
{
struct timeouts *timeouts;
};
struct session_timer *session_timer_create()
{
timeout_error_t err;
struct session_timer *timer = (struct session_timer *)calloc(1, sizeof(struct session_timer));
if (timer == NULL)
{
return NULL;
}
timer->timeouts = timeouts_open(0, &err);
if (timer->timeouts == NULL)
{
goto error;
}
return timer;
error:
session_timer_destroy(timer);
return NULL;
}
void session_timer_destroy(struct session_timer *timer)
{
if (timer)
{
if (timer->timeouts)
{
timeouts_close(timer->timeouts);
}
free(timer);
timer = NULL;
}
}
void session_timer_add_session(struct session_timer *timer, struct session *sess)
{
struct timeout *timeout = &sess->timeout;
timeouts_add(timer->timeouts, timeout, sess->abs_expire_ts);
}
void session_timer_del_session(struct session_timer *timer, struct session *sess)
{
struct timeout *timeout = &sess->timeout;
timeouts_del(timer->timeouts, timeout);
}
struct session *session_timer_expire_session(struct session_timer *timer, uint64_t abs_current_ts)
{
timeouts_update(timer->timeouts, abs_current_ts);
struct timeout *timeout = timeouts_get(timer->timeouts);
if (timeout == NULL)
{
return NULL;
}
struct session *sess = (struct session *)timeout->callback.arg;
return sess;
}

View File

@@ -0,0 +1,26 @@
#ifndef _SESSION_TIMER_H
#define _SESSION_TIMER_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include "session.h"
struct session_timer;
struct session_timer *session_timer_create();
void session_timer_destroy(struct session_timer *timer);
void session_timer_add_session(struct session_timer *timer, struct session *sess);
void session_timer_del_session(struct session_timer *timer, struct session *sess);
/*
* return one session which timeout, or NULL if no session timeout.
* if return session, the session will be removed from timer.
*/
struct session *session_timer_expire_session(struct session_timer *timer, uint64_t abs_current_ts);
#ifdef __cpluscplus
}
#endif
#endif