Skip to content

Commit 67155da

Browse files
Interchanged manager and interact files in sessions as naming conventions and added dedicated session redis for all sessions spawned
1 parent 93ea956 commit 67155da

File tree

2 files changed

+170
-163
lines changed

2 files changed

+170
-163
lines changed

internal/session/interact.go

Lines changed: 153 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,168 @@ package session
22

33
import (
44
"container/list"
5+
"context"
6+
"encoding/json"
7+
"fmt"
8+
"time"
9+
10+
"github.com/google/uuid"
11+
12+
"github.com/PythonHacker24/linux-acl-management-backend/config"
513
)
614

7-
/* create a new session manager */
8-
func NewManager() *Manager {
9-
return &Manager{
10-
sessionsMap: make(map[string]*Session),
11-
sessionOrder: list.New(),
15+
/* for creating a session for user - used by HTTP HANDLERS */
16+
func (m *Manager) CreateSession(username, ipAddress, userAgent string) error {
17+
18+
/* lock the ActiveSessions mutex till the function ends */
19+
m.mutex.Lock()
20+
defer m.mutex.Unlock()
21+
22+
/* check if session exists */
23+
if _, exists := m.sessionsMap[username]; exists {
24+
return fmt.Errorf("user already exists in active sessions")
25+
}
26+
27+
/* Generate session metadata */
28+
sessionID := uuid.New().String()
29+
now := time.Now()
30+
31+
/* create the session */
32+
session := &Session{
33+
ID: sessionID,
34+
Status: StatusActive,
35+
Username: username,
36+
IP: ipAddress,
37+
UserAgent: userAgent,
38+
Expiry: time.Now().Add(time.Duration(config.BackendConfig.AppInfo.SessionTimeout) * time.Hour),
39+
CreatedAt: now,
40+
LastActiveAt: now,
41+
Timer: time.AfterFunc(time.Duration(config.BackendConfig.AppInfo.SessionTimeout) * time.Hour,
42+
func() { m.ExpireSession(username) },
43+
),
44+
CompletedCount: 0,
45+
FailedCount: 0,
46+
TransactionQueue: list.New(),
47+
}
48+
49+
/* add session to active sessions map and list */
50+
element := m.sessionOrder.PushBack(session)
51+
session.listElem = element
52+
53+
m.sessionsMap[username] = session
54+
55+
return nil
56+
}
57+
58+
/* for expiring a session */
59+
func (m *Manager) ExpireSession(username string) {
60+
/* thread safety for the manager */
61+
m.mutex.Lock()
62+
defer m.mutex.Unlock()
63+
64+
/* check if user exists in active sessions */
65+
session, ok := m.sessionsMap[username]
66+
if !ok {
67+
return
68+
}
69+
70+
/* mark the session as expired */
71+
session.Status = StatusExpired
72+
73+
/* remove session from sessionOrder Linked List */
74+
if session.listElem != nil {
75+
m.sessionOrder.Remove(session.listElem)
76+
}
77+
78+
/* TODO: Add expired session to REDIS for persistent logging */
79+
80+
/* remove session from sessionsMap */
81+
delete(m.sessionsMap, username)
82+
}
83+
84+
/* add transaction to a session */
85+
func (m *Manager) AddTransaction(username string, txn interface{}) error {
86+
/* thread safety for the manager */
87+
m.mutex.Lock()
88+
defer m.mutex.Unlock()
89+
90+
/* get the session from sessions map with O(1) runtime */
91+
session, exists := m.sessionsMap[username]
92+
if !exists {
93+
return fmt.Errorf("Session not found")
1294
}
95+
96+
/* thread safety for the session */
97+
session.Mutex.Lock()
98+
defer session.Mutex.Unlock()
99+
100+
/* push transaction into the queue from back */
101+
session.TransactionQueue.PushBack(txn)
102+
103+
return nil
13104
}
14105

15-
/* get next session for round robin */
16-
func (m *Manager) GetNextSession() *Session {
106+
/* refresh the session timer */
107+
func (m *Manager) refreshTimer(username string) error {
108+
/* thread safety for the manager */
17109
m.mutex.Lock()
18110
defer m.mutex.Unlock()
19111

20-
/* check if sessionOrder is empty */
21-
if m.sessionOrder.Len() == 0 {
22-
return nil
112+
/* get session from sessionMap */
113+
session, exists := m.sessionsMap[username]
114+
if !exists {
115+
return fmt.Errorf("Session not found")
23116
}
24117

25-
element := m.sessionOrder.Front()
26-
session := element.Value.(*Session)
118+
/* thread safety for the session */
119+
session.Mutex.Lock()
120+
defer session.Mutex.Unlock()
121+
122+
/* reset the expiry time and last active time */
123+
session.Expiry = time.Now().Add(time.Duration(config.BackendConfig.AppInfo.SessionTimeout) * time.Hour)
124+
session.LastActiveAt = time.Now()
125+
126+
/* stop the session timer */
127+
if session.Timer != nil {
128+
session.Timer.Stop()
129+
}
27130

28-
m.sessionOrder.MoveToBack(element)
29-
return session
131+
/* reset the session timer */
132+
session.Timer = time.AfterFunc(time.Duration(config.BackendConfig.AppInfo.SessionTimeout) * time.Hour,
133+
func() { m.ExpireSession(username) },
134+
)
135+
136+
return nil
30137
}
138+
139+
/* convert session information into frontend safe structure */
140+
func (m *Manager) toDashboardView(username string) (SessionView, error) {
141+
/* thread safety for the manager */
142+
m.mutex.Lock()
143+
defer m.mutex.Unlock()
144+
145+
/* get session from sessionMap */
146+
session, exists := m.sessionsMap[username]
147+
if !exists {
148+
return SessionView{}, fmt.Errorf("Session not found")
149+
}
150+
151+
/* thread safety for the session */
152+
session.Mutex.Lock()
153+
defer session.Mutex.Unlock()
154+
155+
/* can be directly served as JSON in handler */
156+
return SessionView{
157+
ID: session.ID,
158+
Username: session.Username,
159+
IP: session.IP,
160+
UserAgent: session.UserAgent,
161+
CreatedAt: session.CreatedAt,
162+
LastActiveAt: session.LastActiveAt,
163+
Expiry: session.Expiry,
164+
CompletedCount: session.CompletedCount,
165+
FailedCount: session.FailedCount,
166+
PendingCount: session.TransactionQueue.Len(),
167+
}, nil
168+
}
169+

internal/session/manager.go

Lines changed: 17 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ package session
22

33
import (
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

Comments
 (0)