Adapt session timeout checks to a per thread model
Each thread will now check their own list of DCBs for timed out sessions.
This commit is contained in:
parent
30927455ef
commit
5067f3594a
@ -377,6 +377,8 @@ int dcb_accept_SSL(DCB* dcb);
|
||||
int dcb_connect_SSL(DCB* dcb);
|
||||
int dcb_listen(DCB *listener, const char *config, const char *protocol_name);
|
||||
void dcb_append_readqueue(DCB *dcb, GWBUF *buffer);
|
||||
void dcb_enable_session_timeouts();
|
||||
void dcb_process_idle_sessions(int thr);
|
||||
|
||||
/**
|
||||
* DCB flags values
|
||||
|
@ -185,13 +185,6 @@ typedef struct session
|
||||
.stats = SESSION_STATS_INIT, .head = DOWNSTREAM_INIT, .tail = UPSTREAM_INIT, \
|
||||
.state = SESSION_STATE_ALLOC, .ses_chk_tail = CHK_NUM_SESSION}
|
||||
|
||||
/** Whether to do session timeout checks */
|
||||
extern bool check_timeouts;
|
||||
|
||||
/** When the next timeout check is done. This is compared to hkheartbeat in
|
||||
* hk_heartbeat.h */
|
||||
extern long next_timeout_check;
|
||||
|
||||
#define SESSION_PROTOCOL(x, type) DCB_PROTOCOL((x)->client_dcb, type)
|
||||
|
||||
/**
|
||||
@ -231,8 +224,6 @@ SESSION* get_session_by_router_ses(void* rses);
|
||||
void session_enable_log_priority(SESSION* ses, int priority);
|
||||
void session_disable_log_priority(SESSION* ses, int priority);
|
||||
RESULTSET *sessionGetList(SESSIONLISTFILTER);
|
||||
void process_idle_sessions();
|
||||
void enable_session_timeouts();
|
||||
|
||||
/**
|
||||
* Get the transaction state of the session.
|
||||
|
@ -92,6 +92,7 @@
|
||||
#include <sys/un.h>
|
||||
#include <maxscale/alloc.h>
|
||||
#include <maxscale/utils.h>
|
||||
#include <maxscale/platform.h>
|
||||
|
||||
/* The list of all DCBs */
|
||||
static LIST_CONFIG DCBlist =
|
||||
@ -107,6 +108,10 @@ static int *nzombies;
|
||||
static int maxzombies = 0;
|
||||
static SPINLOCK zombiespin = SPINLOCK_INIT;
|
||||
|
||||
/** Variables for session timeout checks */
|
||||
bool check_timeouts = false;
|
||||
thread_local long next_timeout_check = 0;
|
||||
|
||||
void dcb_global_init()
|
||||
{
|
||||
int nthreads = config_threadcount();
|
||||
@ -3479,3 +3484,41 @@ static void dcb_remove_from_list(DCB *dcb)
|
||||
|
||||
spinlock_release(&all_dcbs_lock[dcb->owner]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the timing out of idle connections.
|
||||
*/
|
||||
void dcb_enable_session_timeouts()
|
||||
{
|
||||
check_timeouts = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close sessions that have been idle for too long.
|
||||
*
|
||||
* If the time since a session last sent data is greater than the set value in the
|
||||
* service, it is disconnected. The connection timeout is disabled by default.
|
||||
*/
|
||||
void dcb_process_idle_sessions(int thr)
|
||||
{
|
||||
if (check_timeouts && hkheartbeat >= next_timeout_check)
|
||||
{
|
||||
/** Because the resolution of the timeout is one second, we only need to
|
||||
* check for it once per second. One heartbeat is 100 milliseconds. */
|
||||
next_timeout_check = hkheartbeat + 10;
|
||||
|
||||
for (DCB *dcb = all_dcbs[thr]; dcb; dcb = dcb->memdata.next)
|
||||
{
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER)
|
||||
{
|
||||
SESSION *session = dcb->session;
|
||||
|
||||
if (session->service && session->client_dcb && session->client_dcb->state == DCB_STATE_POLLING &&
|
||||
hkheartbeat - session->client_dcb->last_read > session->service->conn_idle_timeout * 10)
|
||||
{
|
||||
poll_fake_hangup_event(dcb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -752,10 +752,7 @@ poll_waitevents(void *arg)
|
||||
MXS_FREE(tmp);
|
||||
}
|
||||
|
||||
if (check_timeouts && hkheartbeat >= next_timeout_check)
|
||||
{
|
||||
process_idle_sessions();
|
||||
}
|
||||
dcb_process_idle_sessions(thread_id);
|
||||
|
||||
if (thread_data)
|
||||
{
|
||||
|
@ -1052,7 +1052,7 @@ serviceSetTimeout(SERVICE *service, int val)
|
||||
* configured with a idle timeout. */
|
||||
if ((service->conn_idle_timeout = val))
|
||||
{
|
||||
enable_session_timeouts();
|
||||
dcb_enable_session_timeouts();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -56,14 +56,6 @@ static int session_id;
|
||||
|
||||
static struct session session_dummy_struct;
|
||||
|
||||
/**
|
||||
* These two are declared in session.h
|
||||
*/
|
||||
bool check_timeouts = false;
|
||||
long next_timeout_check = 0;
|
||||
|
||||
static SPINLOCK timeout_lock = SPINLOCK_INIT;
|
||||
|
||||
static void session_initialize(void *session);
|
||||
static int session_setup_filters(SESSION *session);
|
||||
static void session_simple_free(SESSION *session, DCB *dcb);
|
||||
@ -894,50 +886,6 @@ session_getUser(SESSION *session)
|
||||
return (session && session->client_dcb) ? session->client_dcb->user : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the timing out of idle connections.
|
||||
*
|
||||
* This will prevent unnecessary acquisitions of the session spinlock if no
|
||||
* service is configured with a session idle timeout.
|
||||
*/
|
||||
void enable_session_timeouts()
|
||||
{
|
||||
check_timeouts = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close sessions that have been idle for too long.
|
||||
*
|
||||
* If the time since a session last sent data is greater than the set value in the
|
||||
* service, it is disconnected. The connection timeout is disabled by default.
|
||||
*/
|
||||
void process_idle_sessions()
|
||||
{
|
||||
if (spinlock_acquire_nowait(&timeout_lock))
|
||||
{
|
||||
if (hkheartbeat >= next_timeout_check)
|
||||
{
|
||||
list_entry_t *current = list_start_iteration(&SESSIONlist);
|
||||
/** Because the resolution of the timeout is one second, we only need to
|
||||
* check for it once per second. One heartbeat is 100 milliseconds. */
|
||||
next_timeout_check = hkheartbeat + 10;
|
||||
while (current)
|
||||
{
|
||||
SESSION *all_session = (SESSION *)current;
|
||||
|
||||
if (all_session->service && all_session->client_dcb && all_session->client_dcb->state == DCB_STATE_POLLING &&
|
||||
hkheartbeat - all_session->client_dcb->last_read > all_session->service->conn_idle_timeout * 10)
|
||||
{
|
||||
poll_fake_hangup_event(all_session->client_dcb);
|
||||
}
|
||||
|
||||
current = list_iterate(&SESSIONlist, current);
|
||||
}
|
||||
}
|
||||
spinlock_release(&timeout_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback structure for the session list extraction
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user