I have a problem where from time to time there are thousands of sessions open on the server and every time between 5% and 10% of those are legitimate, the rest... I have no idea how they were created and why.
In my code the sessions that are for the level OPERATOR or ROOT never expire as long as the browser is still connected (the levels will appear in the pastebin and my code bellow). The AGENT level sessions are alive for 15 minutes, the USER level sessions are alive for 10 minutes and if there is no level I time out the session after 1 minute.
This works fine for many hours, but sometimes when I check the active sessions are thousands of them and they never expire:
https://pastebin.com/raw/x0YASKBS
To control the time the sessions stay active I have a timer set for 20 seconds on each form:
The ServerController's Session Timeout field value is 1.
Anyone have any idea where are those sessions coming from and why they are not timing out?
Edit: It might be a good idea for me to use the "rubber duck debugging method". Almost every time I post a question here, while I'm explaining what's happening I find the problem. Now I'm not sure if this is the fix, but a better code for the StopHeartbeatTimer procedure would handle all legitimate levels and the last "else" would be for everything else, aka timeout right away.
In my code the sessions that are for the level OPERATOR or ROOT never expire as long as the browser is still connected (the levels will appear in the pastebin and my code bellow). The AGENT level sessions are alive for 15 minutes, the USER level sessions are alive for 10 minutes and if there is no level I time out the session after 1 minute.
This works fine for many hours, but sometimes when I check the active sessions are thousands of them and they never expire:
https://pastebin.com/raw/x0YASKBS
To control the time the sessions stay active I have a timer set for 20 seconds on each form:
Code:
procedure TformBalance.HeartbeatTimerAsyncTimer(Sender: TObject; EventParams: TStringList);
begin
StopHeartbeatTimer(HeartbeatTimer);
end;
procedure StopHeartbeatTimer(AHeartbeatTimer: TIWTimer; ACount: integer);
var
iHeartbeats: integer;
begin
if ACount > 0 then
iHeartbeats := ACount
else
// a hearthbeat is every 20 seconds, so the timeout its (iHeartbeats * 20) seconds.
if UserSession.LevelString = 'USER' then
iHeartbeats := 30
else if (UserSession.LevelString = 'AGENT') or
(UserSession.LevelString = 'COMPANY') then
iHeartbeats := 45
else if (UserSession.LevelString = '') then
iHeartbeats := 1
else
Exit; // do not timeout
if AHeartbeatTimer.Tag > iHeartbeats then
AHeartbeatTimer.Enabled := false;
AHeartbeatTimer.Tag := AHeartbeatTimer.Tag + 1;
end;
The ServerController's Session Timeout field value is 1.
Anyone have any idea where are those sessions coming from and why they are not timing out?
Edit: It might be a good idea for me to use the "rubber duck debugging method". Almost every time I post a question here, while I'm explaining what's happening I find the problem. Now I'm not sure if this is the fix, but a better code for the StopHeartbeatTimer procedure would handle all legitimate levels and the last "else" would be for everything else, aka timeout right away.
Code:
// a hearthbeat is every 20 seconds, so the timeout its (iHeartbeats * 20) seconds.
if UserSession.LevelString = 'USER' then
iHeartbeats := 30
else if (UserSession.LevelString = 'AGENT') or
(UserSession.LevelString = 'COMPANY') then
iHeartbeats := 45
else if (UserSession.LevelString = 'ROOT') or
(UserSession.LevelString = 'OPERATOR') then
Exit // do not timeout
else
iHeartbeats := 1;