1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
12 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
13 | };
|
14 | Object.defineProperty(exports, "__esModule", { value: true });
|
15 | const Util_1 = require("./Util");
|
16 | const fs_1 = require("fs");
|
17 | const path_1 = require("path");
|
18 | const exec_pools_1 = require("./exec_pools");
|
19 | const cluster_1 = __importDefault(require("cluster"));
|
20 |
|
21 | class CacheMoudle {
|
22 | constructor(name, ttl, keep) {
|
23 | this.valueCache = {};
|
24 | this.getfresh = false;
|
25 | this.ttl = 0;
|
26 | this.name = '';
|
27 | this.change = false;
|
28 | this.name = name || '';
|
29 | this.ttl = ttl || this.ttl;
|
30 | keep = keep || { type: "unknow" };
|
31 | switch (keep.type) {
|
32 | case 'mongo':
|
33 | this.loader = new Keep_Mongo(this.name, keep);
|
34 | break;
|
35 | case 'file': {
|
36 | this.loader = new Keep_File(this.name, keep);
|
37 | break;
|
38 | }
|
39 | default: {
|
40 | this.loader = new Keep_base(this.name, keep);
|
41 | break;
|
42 | }
|
43 | }
|
44 | }
|
45 |
|
46 | static init() {
|
47 | if (this.handle) {
|
48 | this.handle.stop();
|
49 | }
|
50 | this.handle = Util_1.Util.setInterval(CacheMoudle.update.bind(CacheMoudle), 5 * 1000);
|
51 | return Promise.resolve();
|
52 | }
|
53 | |
54 |
|
55 |
|
56 |
|
57 |
|
58 | static createCache(name, ttl, keep) {
|
59 | if (name == undefined) {
|
60 | return new CacheMoudle(name, ttl, keep);
|
61 | }
|
62 | else {
|
63 | if (!this.cacheMap.hasOwnProperty(name)) {
|
64 | this.cacheMap[name] = new CacheMoudle(name, ttl, keep);
|
65 | }
|
66 | this.thread = Math.ceil(Math.sqrt(Object.keys(this.cacheMap).length));
|
67 | return this.cacheMap[name];
|
68 | }
|
69 | }
|
70 |
|
71 | static removeCache(name) {
|
72 | delete this.cacheMap[name];
|
73 | }
|
74 | static update() {
|
75 | return __awaiter(this, void 0, void 0, function* () {
|
76 | let curr = Date.now();
|
77 | let list = [];
|
78 | for (let key in CacheMoudle.cacheMap) {
|
79 | let unit = CacheMoudle.cacheMap[key];
|
80 | list.push(unit._update.bind(unit));
|
81 | }
|
82 | yield exec_pools_1.execPools(list, this.thread, curr);
|
83 | return Promise.resolve();
|
84 | });
|
85 | }
|
86 | init() {
|
87 | return __awaiter(this, void 0, void 0, function* () {
|
88 | if (!this.loader)
|
89 | return true;
|
90 | this.valueCache = yield this.loader.load();
|
91 | return true;
|
92 | });
|
93 | }
|
94 | |
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 | set(key, value, time) {
|
101 | return __awaiter(this, void 0, void 0, function* () {
|
102 | let change = false;
|
103 | if (!this.valueCache.hasOwnProperty(key)) {
|
104 | this.valueCache[key] = { value: value, time: time || Date.now() };
|
105 | change = true;
|
106 | }
|
107 | else {
|
108 | if (time && this.valueCache[key].time != time) {
|
109 | this.valueCache[key].time = time;
|
110 | change = true;
|
111 | }
|
112 | if (this.valueCache[key].value != value || JSON.stringify(this.valueCache[key].value) != JSON.stringify(value)) {
|
113 | this.valueCache[key].value = value;
|
114 | change = true;
|
115 | }
|
116 | }
|
117 | if (change)
|
118 | yield this.loader.set(key, this.valueCache[key].value, this.valueCache[key].time);
|
119 | return true;
|
120 | });
|
121 | }
|
122 | has(key) {
|
123 | return this.hasOwnProperty(key);
|
124 | }
|
125 | hasOwnProperty(key) {
|
126 | return this.valueCache.hasOwnProperty(key);
|
127 | }
|
128 | get(key) {
|
129 | if (this.valueCache.hasOwnProperty(key)) {
|
130 | if (this.getfresh && this.ttl > 0) {
|
131 | this.valueCache[key].time = Date.now();
|
132 | }
|
133 | return this.valueCache[key].value;
|
134 | }
|
135 | else
|
136 | return undefined;
|
137 | }
|
138 | del(key) {
|
139 | return __awaiter(this, void 0, void 0, function* () {
|
140 | if (!this.valueCache.hasOwnProperty(key))
|
141 | return;
|
142 | delete this.valueCache[key];
|
143 | return yield this.loader.del(key);
|
144 | });
|
145 | }
|
146 | |
147 |
|
148 |
|
149 |
|
150 | forEach(cb) {
|
151 | for (let key in this.valueCache) {
|
152 | if (cb(this.valueCache[key].value, key)) {
|
153 | return this.valueCache[key].value;
|
154 | }
|
155 | }
|
156 | return undefined;
|
157 | }
|
158 | clear() {
|
159 | this.valueCache = {};
|
160 | this.change = true;
|
161 | }
|
162 | _update(curr) {
|
163 | return __awaiter(this, void 0, void 0, function* () {
|
164 |
|
165 | if (this.ttl == 0) {
|
166 | yield this.loader.save();
|
167 | return;
|
168 | }
|
169 | let ttl = this.ttl;
|
170 | if (ttl < 0)
|
171 | ttl = 0;
|
172 | for (let key in this.valueCache) {
|
173 | let unit = this.valueCache[key];
|
174 | if (unit.time + ttl < curr) {
|
175 | yield this.del(key);
|
176 | }
|
177 | }
|
178 | yield this.loader.save();
|
179 | return;
|
180 | });
|
181 | }
|
182 | }
|
183 | exports.CacheMoudle = CacheMoudle;
|
184 | CacheMoudle.thread = 1;
|
185 | CacheMoudle.cacheMap = {};
|
186 | class Keep_base {
|
187 | constructor(name, keep) {
|
188 | }
|
189 | set(key, value) {
|
190 | return __awaiter(this, void 0, void 0, function* () {
|
191 | return true;
|
192 | });
|
193 | }
|
194 | load() {
|
195 | return __awaiter(this, void 0, void 0, function* () {
|
196 | return {};
|
197 | });
|
198 | }
|
199 | save() {
|
200 | return __awaiter(this, void 0, void 0, function* () {
|
201 | return true;
|
202 | });
|
203 | }
|
204 | del(key) {
|
205 | return __awaiter(this, void 0, void 0, function* () {
|
206 | return true;
|
207 | });
|
208 | }
|
209 | }
|
210 | class Keep_Mongo {
|
211 | constructor(name, keep) {
|
212 | this._data = {};
|
213 | this.keep = keep;
|
214 | this.name = name;
|
215 | }
|
216 | load() {
|
217 | return __awaiter(this, void 0, void 0, function* () {
|
218 | let list = yield this.keep.path.get_list(this.name, {}).load();
|
219 | for (let i = 0; i < list.length; i++) {
|
220 | let unit = list.get_at(i);
|
221 | if (!unit)
|
222 | continue;
|
223 | this._data[unit._id] = { value: unit.value, time: unit.time };
|
224 | }
|
225 | return this._data;
|
226 | });
|
227 | }
|
228 | set(key, value, time) {
|
229 | return __awaiter(this, void 0, void 0, function* () {
|
230 | this._data[key] = { value: value, time: time };
|
231 | this.keep.path.update(this.name, { _id: key }, { value: value, time: time }, true);
|
232 | });
|
233 | }
|
234 | save() {
|
235 | return __awaiter(this, void 0, void 0, function* () {
|
236 | return;
|
237 | });
|
238 | }
|
239 | del(key) {
|
240 | return __awaiter(this, void 0, void 0, function* () {
|
241 | if (!this._data.hasOwnProperty(key)) {
|
242 | return;
|
243 | }
|
244 | delete this._data[key];
|
245 | yield this.keep.path.del(this.name, { _id: key });
|
246 | return true;
|
247 | });
|
248 | }
|
249 | }
|
250 | class Keep_File {
|
251 | constructor(name, keep) {
|
252 | this._data = {};
|
253 | this._change = false;
|
254 | this.keep = keep;
|
255 | this.name = name;
|
256 | }
|
257 | load() {
|
258 | return __awaiter(this, void 0, void 0, function* () {
|
259 | if (!this.keep.path || typeof this.keep.path != 'string') {
|
260 | return this._data;
|
261 | }
|
262 | let preID = cluster_1.default.isWorker ? cluster_1.default.worker.id.toString() : '';
|
263 | try {
|
264 | this._data = JSON.parse(fs_1.readFileSync(path_1.join(this.keep.path, this.name + '|' + preID + '.json')).toString() || "{}");
|
265 | }
|
266 | catch (e) {
|
267 | }
|
268 | return this._data;
|
269 | });
|
270 | }
|
271 | save() {
|
272 | return __awaiter(this, void 0, void 0, function* () {
|
273 | if (!this._change)
|
274 | return;
|
275 | if (!fs_1.existsSync(this.keep.path))
|
276 | fs_1.mkdirSync(this.keep.path, { recursive: true });
|
277 | fs_1.writeFileSync(path_1.join(this.keep.path, this.name + '.json'), JSON.stringify(this._data, null, 4), { flag: 'w+' });
|
278 | return;
|
279 | });
|
280 | }
|
281 | set(key, value, time) {
|
282 | return __awaiter(this, void 0, void 0, function* () {
|
283 | this._data[key] = { value, time };
|
284 | this._change = true;
|
285 | });
|
286 | }
|
287 | del(key) {
|
288 | return __awaiter(this, void 0, void 0, function* () {
|
289 | if (!this._data.hasOwnProperty(key)) {
|
290 | return;
|
291 | }
|
292 | this._change = true;
|
293 | delete this._data[key];
|
294 | return true;
|
295 | });
|
296 | }
|
297 | }
|