/
sessions.js
93 lines (81 loc) · 1.98 KB
/
sessions.js
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
/**
* In-memory user sessions for storing userified data.
*/
// TTL for session (after last message from user), 5 min.
// Sessions older than ttl will be removed by cleanup process.
const SESSION_TTL = 5 * 60 * 1000;
// periodically cleanup session data of non-active users
const CLEANUP_INTERVAL = 60 * 1000;
const sessions = new Map();
// Global value for userId.
let currentUserId = null;
let cleanupTimer = null;
const setUserId = userId => currentUserId = userId;
const hasUserId = () => Boolean(currentUserId);
/**
* Updates or creates user session with actual timestamp.
*/
const getOrCreateSession = userId => {
let session = sessions.get(userId);
if (!session) {
session = {};
sessions.set(userId, session);
}
// update timestamp on any user activity with session
// use $ to avoid conflicts with user data keys
session.$timestamp = Date.now();
return session;
};
/**
* Gets value for current user with provided key
* @param {String} key
* @returns {*}
*/
const getValue = key => {
const session = getOrCreateSession(currentUserId);
return session[key];
};
/**
* Sets value for current user with provided key.
* @param {String} key
* @param {*} value
* @returns {*}
*/
const setValue = (key, value) => {
const session = getOrCreateSession(currentUserId);
session[key] = value;
};
/**
* Starts cleanup service.
*/
const startCleanupService = () => {
if (cleanupTimer) {
clearInterval(cleanupTimer);
}
cleanupTimer = setInterval(cleanup, CLEANUP_INTERVAL);
if (cleanupTimer.unref) {
cleanupTimer.unref();
}
};
/**
* Cleanups outdated sessions.
*/
const cleanup = () => {
const now = Date.now();
sessions.forEach((session, key) => {
const isOutdated = Math.abs(now - session.$timestamp) >= SESSION_TTL;
if (isOutdated) {
sessions.delete(key);
}
});
};
const getSessions = () => sessions;
module.exports = {
getOrCreateSession,
startCleanupService,
setUserId,
hasUserId,
getValue,
setValue,
getSessions,
};