Skip to content

Commit dbfa70d

Browse files
created redis.go for session only
1 parent 71dbb83 commit dbfa70d

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

internal/session/redis.go

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package session
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"time"
8+
9+
"github.com/PythonHacker24/linux-acl-management-backend/internal/types"
10+
)
11+
12+
/* we make use of Redis hashes for this application */
13+
14+
/* TODO: make the operations below thread safe with mutexes*/
15+
16+
/* store session into Redis database */
17+
func (m *Manager) saveSession(username string) error {
18+
ctx := context.Background()
19+
20+
/* thread safety for the manager */
21+
m.mutex.Lock()
22+
defer m.mutex.Unlock()
23+
24+
/* find the session in session map */
25+
session, ok := m.sessionsMap[username]
26+
if !ok {
27+
return fmt.Errorf("username not found in session")
28+
}
29+
30+
/* thread safety for the session */
31+
session.Mutex.Lock()
32+
defer session.Mutex.Unlock()
33+
34+
/* session key for redis */
35+
key := fmt.Sprintf("session:%s", session.ID)
36+
37+
/* serialize the session with relevant information */
38+
sessionSerialized := session.serializeSessionForRedis()
39+
40+
if err := m.redis.HSet(ctx, key, sessionSerialized).Err(); err != nil {
41+
return fmt.Errorf("failed to save session to Redis: %w", err)
42+
}
43+
44+
return nil
45+
}
46+
47+
/* update expiry time in session */
48+
func (m *Manager) updateSessionExpiry(username string) error {
49+
50+
/*
51+
function expects that new expiry time is already set in the session
52+
*/
53+
54+
ctx := context.Background()
55+
56+
/* thread safety for the manager */
57+
m.mutex.Lock()
58+
defer m.mutex.Unlock()
59+
60+
/* find the session in session map */
61+
session, ok := m.sessionsMap[username]
62+
if !ok {
63+
return fmt.Errorf("username not found in session")
64+
}
65+
66+
/* thread safety for the session */
67+
session.Mutex.Lock()
68+
defer session.Mutex.Unlock()
69+
70+
/* create a key for Redis operation */
71+
key := fmt.Sprintf("session:%s", session.ID)
72+
73+
/* convert the expiry time to */
74+
formattedExpiry := session.Expiry.Format(time.RFC3339)
75+
76+
/* update just the expiry field */
77+
err := m.redis.HSet(ctx, key, "expiry", formattedExpiry).Err()
78+
if err != nil {
79+
return fmt.Errorf("failed to update session expiry in Redis: %w", err)
80+
}
81+
82+
return nil
83+
}
84+
85+
/* TODO: Sessions must be marked expired when main.go exits */
86+
87+
/* update status of the session - update and set expired operations will be done with this */
88+
func (m *Manager) updateSessionStatus(username string, status Status) error {
89+
90+
ctx := context.Background()
91+
92+
/* thread safety for the manager */
93+
m.mutex.Lock()
94+
defer m.mutex.Unlock()
95+
96+
/* find the session in session map */
97+
session, ok := m.sessionsMap[username]
98+
if !ok {
99+
return fmt.Errorf("username not found in session")
100+
}
101+
102+
/* thread safety for the session */
103+
session.Mutex.Lock()
104+
defer session.Mutex.Unlock()
105+
106+
/* create a key for Redis operation */
107+
key := fmt.Sprintf("session:%s", session.ID)
108+
109+
/* update the session status */
110+
err := m.redis.HSet(ctx, key, "status", status).Err()
111+
if err != nil {
112+
return fmt.Errorf("failed to mark session as expired in Redis: %w", err)
113+
}
114+
115+
return nil
116+
}
117+
118+
/* save transaction results to redis */
119+
func (m *Manager) saveTransactionResults(username string, txResult types.Transaction) error {
120+
121+
ctx := context.Background()
122+
123+
/* thread safety for the manager */
124+
m.mutex.Lock()
125+
defer m.mutex.Unlock()
126+
127+
/* find the session in session map */
128+
session, ok := m.sessionsMap[username]
129+
if !ok {
130+
return fmt.Errorf("username not found in session")
131+
}
132+
133+
/* thread safety for the session */
134+
session.Mutex.Lock()
135+
defer session.Mutex.Unlock()
136+
137+
/* get the session ID */
138+
sessionID := session.ID
139+
140+
/* create a key for Redis operation */
141+
key := fmt.Sprintf("session:%s:txresults", sessionID)
142+
143+
/* marshal transaction result to JSON */
144+
resultBytes, err := json.Marshal(txResult)
145+
if err != nil {
146+
return fmt.Errorf("failed to marshal transaction result: %w", err)
147+
}
148+
149+
/* push the transaction result in the back of the list */
150+
return m.redis.RPush(ctx, key, resultBytes).Err()
151+
}
152+
153+
func (m *Manager) getTransactionResults(username string, limit int) ([]types.TransactionResult, error) {
154+
ctx := context.Background()
155+
156+
/* thread safety for the manager */
157+
m.mutex.Lock()
158+
defer m.mutex.Unlock()
159+
160+
/* find the session in session map */
161+
session, ok := m.sessionsMap[username]
162+
if !ok {
163+
return nil, fmt.Errorf("username not found in session")
164+
}
165+
166+
/* thread safety for the session */
167+
session.Mutex.Lock()
168+
defer session.Mutex.Unlock()
169+
170+
/* get the session ID */
171+
sessionID := session.ID
172+
173+
/* create a key for Redis operation */
174+
key := fmt.Sprintf("session:%s:txresults", sessionID)
175+
176+
/* returns transactions in chronological order */
177+
values, err := m.redis.LRange(ctx, key, int64(-limit), -1).Result()
178+
if err != nil {
179+
return nil, fmt.Errorf("failed to get transaction results: %w", err)
180+
}
181+
182+
/* converts each JSON string back into a TransactionResult */
183+
results := make([]types.TransactionResult, 0, len(values))
184+
for _, val := range values {
185+
var result types.TransactionResult
186+
if err := json.Unmarshal([]byte(val), &result); err != nil {
187+
/* skip malformed results */
188+
continue
189+
}
190+
results = append(results, result)
191+
}
192+
193+
return results, nil
194+
}

0 commit comments

Comments
 (0)