1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
| ///////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2015 by Charta Software B.V. //
// All rights reserved //
// //
// Version: 1.7.0.83525 //
// Web site: https://pascal.chartasoftware.com/ //
// //
// This code and information are provided "as is" without warranty of //
// any kind. Dissemination of this information or reproduction of //
// this material is strictly forbidden unless prior written permission //
// is obtained from Charta Software B.V.. //
// //
///////////////////////////////////////////////////////////////////////////
unit WebSite.Session.Manager;
interface
uses
Collection.List.Sorted.ByKey,
Task,
Text,
Thread.Lock,
Uuid,
WebSite.Session,
WebSite.Session.Factory;
type
TWebSiteSessionManager = class(TObject)
protected
Sessions: TSortedByKeyList<TUuid, TWebSiteSession>;
LogoutTask: TTask;
procedure CleanupSessions();
public
Lock: TThreadLock;
SessionFactory: TWebSiteSessionFactory;
constructor Create(); virtual;
destructor Destroy(); override;
function GetSessionWithIdentifier(const Identifier: TUuid): TWebSiteSession;
procedure AddSession(Session: TWebSiteSession);
procedure RemoveSession(Session: TWebSiteSession);
end;
TWebSiteSessionLogoutTask = class(TTask)
protected
SessionManager: TWebSiteSessionManager;
public
constructor Create(SessionManager: TWebSiteSessionManager); reintroduce; virtual;
procedure Execute(); override;
function ToText(): TText; override;
end;
implementation
uses
DateTime.TickCount,
Object_.Reference.Owner,
Task.Scheduler;
{ TWebSiteSessionManager }
procedure TWebSiteSessionManager.AddSession(Session: TWebSiteSession);
begin
Session.LastAccessTickCount := TTickCount.GetCurrent();
Sessions.Add(Session);
end;
procedure TWebSiteSessionManager.CleanupSessions();
var
Session: TWebSiteSession;
CurrentTickCount: TTickCount;
begin
Lock.Acquire();
try
CurrentTickCount := TTickCount.GetCurrent();
for Session in Sessions do
Session.LogoutIfExpired(CurrentTickCount);
finally
Lock.Release();
end;
end;
constructor TWebSiteSessionManager.Create();
begin
inherited Create();
Lock := TThreadLock.Create();
Sessions := TSortedByKeyList<TUuid, TWebSiteSession>.Create();
Sessions.ElementManager := TReferenceOwner<TWebSiteSession>.Create();
Sessions.KeyComparator := TUuid.TCompare.Instance;
Sessions.Projector := TWebSiteSession.TKey.Instance;
LogoutTask := TWebSiteSessionLogoutTask.Create(Self);
LogoutTask.AddReference();
TTaskScheduler.Instance.ExecuteRecurringly(LogoutTask, 10 * 1000);
end;
destructor TWebSiteSessionManager.Destroy();
begin
TTaskScheduler.Instance.Unschedule(LogoutTask);
LogoutTask.ReleaseReference();
Sessions.Free();
Lock.Free();
inherited Destroy();
end;
function TWebSiteSessionManager.GetSessionWithIdentifier(const Identifier: TUuid): TWebSiteSession;
begin
Result := Sessions.Find(Identifier);
if Result <> nil then
Result.LastAccessTickCount := TTickCount.GetCurrent();
end;
procedure TWebSiteSessionManager.RemoveSession(Session: TWebSiteSession);
begin
Sessions.Remove(Session);
end;
{ TWebSiteSessionLogoutTask }
constructor TWebSiteSessionLogoutTask.Create(SessionManager: TWebSiteSessionManager);
begin
inherited Create();
Self.SessionManager := SessionManager;
end;
procedure TWebSiteSessionLogoutTask.Execute();
begin
SessionManager.CleanupSessions();
end;
function TWebSiteSessionLogoutTask.ToText(): TText;
begin
Result := 'Session log out';
end;
end.
|