saico 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -33
- package/index.js +13 -12
- package/itask.js +3 -0
- package/msgs.js +38 -182
- package/package.json +1 -1
- package/redis.js +7 -5
- package/saico.js +210 -161
- package/store.js +1 -126
package/store.js
CHANGED
|
@@ -4,46 +4,10 @@ const crypto = require('crypto');
|
|
|
4
4
|
|
|
5
5
|
let _instance = null;
|
|
6
6
|
|
|
7
|
-
class DynamoBackend {
|
|
8
|
-
constructor({ table, aws }) {
|
|
9
|
-
this.table = table;
|
|
10
|
-
this.aws = aws;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async save(id, data) {
|
|
14
|
-
await this.aws.dynamoPutItem(this.table, {
|
|
15
|
-
id,
|
|
16
|
-
data: typeof data === 'string' ? data : JSON.stringify(data),
|
|
17
|
-
updated_at: Date.now()
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async load(id) {
|
|
22
|
-
const item = await this.aws.dynamoGetItem(this.table, 'id', id);
|
|
23
|
-
if (!item)
|
|
24
|
-
return null;
|
|
25
|
-
const data = item.data;
|
|
26
|
-
if (typeof data === 'string') {
|
|
27
|
-
try { return JSON.parse(data); }
|
|
28
|
-
catch (e) { return data; }
|
|
29
|
-
}
|
|
30
|
-
return data;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async delete(id) {
|
|
34
|
-
await this.aws.dynamoDeleteItem(this.table, 'id', id);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
7
|
class Store {
|
|
39
8
|
constructor(config = {}) {
|
|
40
9
|
this._redis = null;
|
|
41
|
-
this._backends = {};
|
|
42
10
|
this._config = config;
|
|
43
|
-
|
|
44
|
-
if (config.dynamodb) {
|
|
45
|
-
this._backends.dynamodb = new DynamoBackend(config.dynamodb);
|
|
46
|
-
}
|
|
47
11
|
}
|
|
48
12
|
|
|
49
13
|
static get instance() {
|
|
@@ -56,7 +20,6 @@ class Store {
|
|
|
56
20
|
|
|
57
21
|
static init(config = {}) {
|
|
58
22
|
_instance = new Store(config);
|
|
59
|
-
// If redis module provided or redis is already initialized, grab the client
|
|
60
23
|
const redis = require('./redis.js');
|
|
61
24
|
if (redis.rclient)
|
|
62
25
|
_instance._redis = redis.rclient;
|
|
@@ -67,97 +30,9 @@ class Store {
|
|
|
67
30
|
this._redis = rclient;
|
|
68
31
|
}
|
|
69
32
|
|
|
70
|
-
addBackend(name, backend) {
|
|
71
|
-
this._backends[name] = backend;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
33
|
generateId() {
|
|
75
34
|
return crypto.randomBytes(8).toString('hex');
|
|
76
35
|
}
|
|
77
|
-
|
|
78
|
-
async save(id, data) {
|
|
79
|
-
const key = 'saico:' + id;
|
|
80
|
-
const serialized = typeof data === 'string' ? data : JSON.stringify(data);
|
|
81
|
-
|
|
82
|
-
// Always save to Redis if available
|
|
83
|
-
if (this._redis) {
|
|
84
|
-
try {
|
|
85
|
-
await this._redis.set(key, serialized);
|
|
86
|
-
} catch (e) {
|
|
87
|
-
console.error('Store: Redis save error:', e.message);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Save to all configured backends
|
|
92
|
-
for (const [name, backend] of Object.entries(this._backends)) {
|
|
93
|
-
try {
|
|
94
|
-
await backend.save(id, data);
|
|
95
|
-
} catch (e) {
|
|
96
|
-
console.error(`Store: ${name} backend save error:`, e.message);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
async load(id) {
|
|
102
|
-
const key = 'saico:' + id;
|
|
103
|
-
|
|
104
|
-
// Try Redis first
|
|
105
|
-
if (this._redis) {
|
|
106
|
-
try {
|
|
107
|
-
const cached = await this._redis.get(key);
|
|
108
|
-
if (cached) {
|
|
109
|
-
try { return JSON.parse(cached); }
|
|
110
|
-
catch (e) { return cached; }
|
|
111
|
-
}
|
|
112
|
-
} catch (e) {
|
|
113
|
-
console.error('Store: Redis load error:', e.message);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Fall back to backends
|
|
118
|
-
for (const [name, backend] of Object.entries(this._backends)) {
|
|
119
|
-
try {
|
|
120
|
-
const data = await backend.load(id);
|
|
121
|
-
if (data) {
|
|
122
|
-
// Cache to Redis for next time
|
|
123
|
-
if (this._redis) {
|
|
124
|
-
try {
|
|
125
|
-
const serialized = typeof data === 'string'
|
|
126
|
-
? data : JSON.stringify(data);
|
|
127
|
-
await this._redis.set(key, serialized);
|
|
128
|
-
} catch (e) {
|
|
129
|
-
console.error('Store: Redis cache-back error:', e.message);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return data;
|
|
133
|
-
}
|
|
134
|
-
} catch (e) {
|
|
135
|
-
console.error(`Store: ${name} backend load error:`, e.message);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async delete(id) {
|
|
143
|
-
const key = 'saico:' + id;
|
|
144
|
-
|
|
145
|
-
if (this._redis) {
|
|
146
|
-
try {
|
|
147
|
-
await this._redis.del(key);
|
|
148
|
-
} catch (e) {
|
|
149
|
-
console.error('Store: Redis delete error:', e.message);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
for (const [name, backend] of Object.entries(this._backends)) {
|
|
154
|
-
try {
|
|
155
|
-
await backend.delete(id);
|
|
156
|
-
} catch (e) {
|
|
157
|
-
console.error(`Store: ${name} backend delete error:`, e.message);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
36
|
}
|
|
162
37
|
|
|
163
|
-
module.exports = { Store
|
|
38
|
+
module.exports = { Store };
|