-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
106 lines (91 loc) · 2.38 KB
/
index.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
94
95
96
97
98
99
100
101
102
103
104
105
106
'use strict';
const async = require('async');
const EventEmitter = require('events');
// We have three encoding implementations in this repository (snappy, gzip, and lz4).
// In testing, gzip was too slow for large sessions (~2mb).
// lz4 and snappy were about the same speed, but lz4 offered slightly better compression
// in our testing data set.
const LZ4 = require('./encodings/lz4.js');
module.exports = class SessionCompress extends EventEmitter {
constructor(store) {
super();
this.store = store;
this._encoding = new LZ4();
// Some methods are optional, so only add them if the backing store has them.
for (let meth of ['destroy', 'clear', 'length']) {
if (this.store[meth]) {
this.add(meth);
}
}
// Touch and all need special behavior, so can't do it in the above loop.
if (this.store.touch) {
this.touch = (sid, session, cb) => {
this.compress(session, (err, compressed) => {
if (err) {
cb(err);
return
}
this.store.touch(sid, compressed, cb);
});
}
}
if (this.store.all) {
this.all = (cb) => {
this.store.all((err, sessions) => {
if (err) {
cb(err);
return
}
async.map(sessions, this.decompress.bind(this), cb);
});
}
}
}
add(meth) {
this[meth] = (...args) => {
this.store[meth].apply(this.store, args);
}
}
get(sid, cb) {
this.store.get(sid, (err, session) => {
if (err) {
cb(err);
return
}
this.decompress(session, cb);
});
}
set(sid, session, cb) {
this.compress(session, (err, compressed) => {
this.store.set(sid, compressed, cb);
});
}
compress(session, cb) {
let uncompressed;
try {
uncompressed = JSON.stringify(session);
} catch (err) {
cb(err);
return
}
this._encoding.compress(uncompressed, (err, compressed) => {
if (compressed) {
console.log(`turned len ${uncompressed.length} to len ${compressed.length}`)
}
cb(err, compressed);
});
}
decompress(session, cb) {
this._encoding.decompress(session, (err, uncompressed) => {
if (err) {
cb(err);
return
}
try {
cb(null, JSON.parse(uncompressed));
} catch (err) {
cb(err);
}
});
}
}