@@ -2,13 +2,9 @@ package session
22
33import (
44 "container/list"
5- "fmt"
65 "sync"
7- "time"
86
9- "github.com/google/uuid"
10-
11- "github.com/PythonHacker24/linux-acl-management-backend/config"
7+ "github.com/PythonHacker24/linux-acl-management-backend/internal/session/redis"
128)
139
1410/*
@@ -23,159 +19,31 @@ type Manager struct {
2319 sessionsMap map [string ]* Session
2420 sessionOrder * list.List
2521 mutex sync.RWMutex
22+ redis redis.RedisClient
2623}
2724
28- /* for creating a session for user - used by HTTP HANDLERS */
29- func (m * Manager ) CreateSession (username , ipAddress , userAgent string ) error {
30-
31- /* lock the ActiveSessions mutex till the function ends */
32- m .mutex .Lock ()
33- defer m .mutex .Unlock ()
34-
35- /* check if session exists */
36- if _ , exists := m .sessionsMap [username ]; exists {
37- return fmt .Errorf ("user already exists in active sessions" )
38- }
39-
40- /* Generate session metadata */
41- sessionID := uuid .New ().String ()
42- now := time .Now ()
43-
44- /* create the session */
45- session := & Session {
46- ID : sessionID ,
47- Status : StatusActive ,
48- Username : username ,
49- IP : ipAddress ,
50- UserAgent : userAgent ,
51- Expiry : time .Now ().Add (time .Duration (config .BackendConfig .AppInfo .SessionTimeout ) * time .Hour ),
52- CreatedAt : now ,
53- LastActiveAt : now ,
54- Timer : time .AfterFunc (time .Duration (config .BackendConfig .AppInfo .SessionTimeout ) * time .Hour ,
55- func () { m .ExpireSession (username ) },
56- ),
57- CompletedCount : 0 ,
58- FailedCount : 0 ,
59- TransactionQueue : list .New (),
60- }
61-
62- /* add session to active sessions map and list */
63- element := m .sessionOrder .PushBack (session )
64- session .listElem = element
65-
66- m .sessionsMap [username ] = session
67-
68- return nil
69- }
70-
71- /* for expiring a session */
72- func (m * Manager ) ExpireSession (username string ) {
73- /* thread safety for the manager */
74- m .mutex .Lock ()
75- defer m .mutex .Unlock ()
76-
77- /* check if user exists in active sessions */
78- session , ok := m .sessionsMap [username ]
79- if ! ok {
80- return
81- }
82-
83- /* disable the session */
84- session .Status = StatusExpired
85-
86- /* remove session from sessionOrder Linked List */
87- if session .listElem != nil {
88- m .sessionOrder .Remove (session .listElem )
89- }
90-
91- /* TODO: Add expired session to REDIS for persistent logging */
92-
93- /* remove session from sessionsMap */
94- delete (m .sessionsMap , username )
95- }
96-
97- /* add transaction to a session */
98- func (m * Manager ) AddTransaction (username string , txn interface {}) error {
99- /* thread safety for the manager */
100- m .mutex .Lock ()
101- defer m .mutex .Unlock ()
102-
103- /* get the session from sessions map with O(1) runtime */
104- session , exists := m .sessionsMap [username ]
105- if ! exists {
106- return fmt .Errorf ("Session not found" )
25+ /* create a new session manager */
26+ func NewManager (redis redis.RedisClient ) * Manager {
27+ return & Manager {
28+ sessionsMap : make (map [string ]* Session ),
29+ sessionOrder : list .New (),
30+ redis : redis ,
10731 }
108-
109- /* thread safety for the session */
110- session .Mutex .Lock ()
111- defer session .Mutex .Unlock ()
112-
113- /* push transaction into the queue from back */
114- session .TransactionQueue .PushBack (txn )
115-
116- return nil
11732}
11833
119- /* refresh the session timer */
120- func (m * Manager ) RefreshTimer (username string ) error {
121- /* thread safety for the manager */
34+ /* get next session for round robin */
35+ func (m * Manager ) GetNextSession () * Session {
12236 m .mutex .Lock ()
12337 defer m .mutex .Unlock ()
12438
125- /* get session from sessionMap */
126- session , exists := m .sessionsMap [username ]
127- if ! exists {
128- return fmt .Errorf ("Session not found" )
39+ /* check if sessionOrder is empty */
40+ if m .sessionOrder .Len () == 0 {
41+ return nil
12942 }
13043
131- /* thread safety for the session */
132- session .Mutex .Lock ()
133- defer session .Mutex .Unlock ()
134-
135- /* reset the expiry time and last active time */
136- session .Expiry = time .Now ().Add (time .Duration (config .BackendConfig .AppInfo .SessionTimeout ) * time .Hour )
137- session .LastActiveAt = time .Now ()
138-
139- /* stop the session timer */
140- if session .Timer != nil {
141- session .Timer .Stop ()
142- }
44+ element := m .sessionOrder .Front ()
45+ session := element .Value .(* Session )
14346
144- /* reset the session timer */
145- session .Timer = time .AfterFunc (time .Duration (config .BackendConfig .AppInfo .SessionTimeout ) * time .Hour ,
146- func () { m .ExpireSession (username ) },
147- )
148-
149- return nil
47+ m .sessionOrder .MoveToBack (element )
48+ return session
15049}
151-
152- /* convert session information into frontend safe structure */
153- func (m * Manager ) ToDashboardView (username string ) (SessionView , error ) {
154- /* thread safety for the manager */
155- m .mutex .Lock ()
156- defer m .mutex .Unlock ()
157-
158- /* get session from sessionMap */
159- session , exists := m .sessionsMap [username ]
160- if ! exists {
161- return SessionView {}, fmt .Errorf ("Session not found" )
162- }
163-
164- /* thread safety for the session */
165- session .Mutex .Lock ()
166- defer session .Mutex .Unlock ()
167-
168- /* can be directly served as JSON in handler */
169- return SessionView {
170- ID : session .ID ,
171- Username : session .Username ,
172- IP : session .IP ,
173- UserAgent : session .UserAgent ,
174- CreatedAt : session .CreatedAt ,
175- LastActiveAt : session .LastActiveAt ,
176- Expiry : session .Expiry ,
177- CompletedCount : session .CompletedCount ,
178- FailedCount : session .FailedCount ,
179- PendingCount : session .TransactionQueue .Len (),
180- }, nil
181- }
0 commit comments