@maiyunnet/kebab 3.2.35 → 4.0.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/lib/kv.js CHANGED
@@ -1,708 +1,69 @@
1
1
  /**
2
2
  * Project: Kebab, User: JianSuoQiYue
3
3
  * Date: 2019-5-30 19:25:22
4
- * Last: 2020-3-28 18:54:04, 2022-09-12 23:24:45, 2022-09-22 01:06:22, 2024-2-21 13:32:56, 2024-8-21 16:59:57
4
+ * Last: 2020-3-28 18:54:04, 2022-09-12 23:24:45, 2022-09-22 01:06:22, 2024-2-21 13:32:56, 2024-8-21 16:59:57, 2025-11-6 14:56:45
5
5
  */
6
- // --- Pool 是使用时必须要一个用户创建一份的,Connection 是池子里获取的 ---
7
- // --- 为啥 Pool 要独立,因为有些配置项目不能存在 Connection 是用户单独使用的,例如 pre ---
8
6
  // --- 第三方 ---
9
7
  import * as redis from '@litert/redis';
10
- import * as lTime from '#kebab/lib/time.js';
8
+ // --- 库和定义 ---
11
9
  import * as lText from '#kebab/lib/text.js';
12
10
  import * as lCore from '#kebab/lib/core.js';
13
- /** --- 连接列表(同一个 host、port、index、auth 只有一个连接) --- */
11
+ /** --- 连接列表(同一个 host、port、index 只有一个连接) --- */
14
12
  const connections = [];
15
- /**
16
- * --- 计划任务 10 秒一次,关闭超过 30 秒不活动的连接 ---
17
- */
18
- async function checkConnection() {
19
- const now = lTime.stamp();
20
- for (let i = 0; i < connections.length; ++i) {
21
- const connection = connections[i];
22
- if (connection.isLost()) {
23
- // --- 连接已经丢失,移除 ---
24
- await connection.end();
25
- connections.splice(i, 1);
26
- --i;
27
- continue;
28
- }
29
- if (connection.isUsing()) {
30
- // --- 连接正在被使用,看看是否使用超过 30 秒,超过则不是正常状态 ---
31
- if (connection.getLast() <= now - 30) {
32
- // --- 30 秒之前开始的 ---
33
- const msg = `[KV][checkConnection] There is a transactional connection[${i}] that is not closed.`;
34
- lCore.display(msg);
35
- lCore.log({}, msg, '-error');
36
- await connection.end();
37
- connections.splice(i, 1);
38
- --i;
39
- }
40
- continue;
41
- }
42
- if (connection.getLast() <= now - 30) {
43
- // --- 超 30 秒未被使用,则关闭 ---
44
- await connection.end();
45
- connections.splice(i, 1);
46
- --i;
47
- continue;
48
- }
49
- // --- 30 秒内使用过,看看连接是否正常 ---
50
- if (await connection.ping(false)) {
51
- // --- 正常 ---
52
- continue;
53
- }
54
- // --- 连接有问题,直接关闭 ---
55
- await connection.end();
56
- connections.splice(i, 1);
57
- --i;
58
- }
59
- setTimeout(function () {
60
- checkConnection().catch(() => { });
61
- }, 10_000);
62
- }
63
- setTimeout(function () {
64
- checkConnection().catch(() => { });
65
- }, 10_000);
66
- export class Pool {
13
+ export class Kv {
67
14
  constructor(ctr, etc) {
68
15
  const configKv = ctr.getPrototype('_config').kv;
69
- this._etc = {
70
- 'host': etc?.host ?? configKv.host,
71
- 'port': etc?.port ?? configKv.port,
72
- 'index': etc?.index ?? configKv.index,
73
- 'pre': etc?.pre ?? configKv.pre,
74
- 'user': etc?.user ?? configKv.user,
75
- 'pwd': etc?.pwd ?? configKv.pwd,
76
- };
77
- }
78
- /**
79
- * --- 设定一个值 ---
80
- * @param key
81
- * @param val
82
- * @param ttl 秒,0 为不限制
83
- * @param mod 设置模式: 空,nx(key不存在才建立),xx(key存在才修改)
84
- */
85
- async set(key, val, ttl = 0, mod = '') {
86
- const conn = await this._getConnection();
87
- if (!conn) {
88
- return false;
89
- }
90
- const r = await conn.set(key, val, ttl, mod, this._etc);
91
- conn.used();
92
- return r;
93
- }
94
- /**
95
- * --- 添加一个值,存在则不变 ---
96
- * @param key
97
- * @param val
98
- * @param ttl 秒,0 为不限制
99
- */
100
- async add(key, val, ttl = 0) {
101
- const conn = await this._getConnection();
102
- if (!conn) {
103
- return false;
104
- }
105
- const r = await conn.add(key, val, ttl, this._etc);
106
- conn.used();
107
- return r;
108
- }
109
- /**
110
- * --- 替换一个存在的值 ---
111
- * @param key
112
- * @param val
113
- * @param ttl 秒,0 为不限制
114
- */
115
- async replace(key, val, ttl = 0) {
116
- const conn = await this._getConnection();
117
- if (!conn) {
118
- return false;
119
- }
120
- const r = await conn.replace(key, val, ttl, this._etc);
121
- conn.used();
122
- return r;
123
- }
124
- /**
125
- * --- 向已存在的值后追加数据 ---
126
- * @param key
127
- * @param val
128
- */
129
- async append(key, val) {
130
- const conn = await this._getConnection();
131
- if (!conn) {
132
- return false;
133
- }
134
- const r = await conn.append(key, val, this._etc);
135
- conn.used();
136
- return r;
137
- }
138
- /**
139
- * --- 向已存在的值之前追加数据 ---
140
- * @param key
141
- * @param val
142
- */
143
- async prepend(key, val) {
144
- const conn = await this._getConnection();
145
- if (!conn) {
146
- return false;
147
- }
148
- const r = await conn.prepend(key, val, this._etc);
149
- conn.used();
150
- return r;
151
- }
152
- /**
153
- * --- 检测 key 是否存在 ---
154
- * @param keys
155
- */
156
- async exists(keys) {
157
- const conn = await this._getConnection();
158
- if (!conn) {
159
- return 0;
160
- }
161
- const r = await conn.exists(keys, this._etc);
162
- conn.used();
163
- return r;
164
- }
165
- /**
166
- * --- 获取字符串 ---
167
- * @param key
168
- */
169
- async get(key) {
170
- const conn = await this._getConnection();
171
- if (!conn) {
172
- return null;
173
- }
174
- const r = await conn.get(key, this._etc);
175
- conn.used();
176
- return r;
177
- }
178
- /**
179
- * --- 获取相应的剩余有效期秒数 ---
180
- * @param key
181
- */
182
- async ttl(key) {
183
- const conn = await this._getConnection();
184
- if (!conn) {
185
- return null;
186
- }
187
- const r = await conn.ttl(key, this._etc);
188
- conn.used();
189
- return r;
190
- }
191
- /**
192
- * --- 获取相应的剩余有效期毫秒数 ---
193
- * @param key
194
- */
195
- async pttl(key) {
196
- const conn = await this._getConnection();
197
- if (!conn) {
198
- return null;
199
- }
200
- const r = await conn.pttl(key, this._etc);
201
- conn.used();
202
- return r;
203
- }
204
- /**
205
- * --- 批量获取值 ---
206
- * @param keys key 序列
207
- */
208
- async mSet(rows) {
209
- const conn = await this._getConnection();
210
- if (!conn) {
211
- return false;
16
+ const host = etc?.host ?? configKv.host;
17
+ const port = etc?.port ?? configKv.port;
18
+ this._index = etc?.index ?? configKv.index;
19
+ this._pre = etc?.pre ?? configKv.pre;
20
+ const item = connections.find(item => (item.host === host) && (item.port === port) && (item.index === this._index));
21
+ if (item) {
22
+ this._new = false;
23
+ this._link = item.link;
24
+ return;
212
25
  }
213
- const r = await conn.mSet(rows, this._etc);
214
- conn.used();
215
- return r;
26
+ this._new = true;
27
+ this._link = redis.createCommandClient({
28
+ 'host': host,
29
+ 'port': port,
30
+ });
31
+ this._link.on('error', err => {
32
+ lCore.debug('[KV][constructor][error]', err);
33
+ }).on('end', () => {
34
+ // --- 连接断开,不过没关系,执行命令时会自动重连 ---
35
+ }).on('close', () => {
36
+ // --- 连接断开,不过没关系,执行命令时会自动重连 ---
37
+ });
38
+ connections.push({
39
+ 'host': host,
40
+ 'port': port,
41
+ 'index': this._index,
42
+ 'link': this._link,
43
+ });
216
44
  }
217
- /**
218
- * --- 批量获取值 ---
219
- * @param keys key 序列
220
- */
221
- async mGet(keys) {
222
- const conn = await this._getConnection();
223
- if (conn) {
224
- const r = await conn.mGet(keys, this._etc);
225
- conn.used();
226
- return r;
227
- }
228
- else {
229
- const rtn = {};
230
- for (const key of keys) {
231
- rtn[key] = null;
45
+ /** --- 初始化连接 --- */
46
+ async init(ctr, etc) {
47
+ try {
48
+ if (!this._new) {
49
+ // --- 不是新连接,不需要初始化 ---
50
+ return true;
232
51
  }
233
- return rtn;
234
- }
235
- }
236
- /**
237
- * --- 获取 json 对象 ---
238
- * @param key
239
- * @returns false 表示系统错误, null 表示不存在, 其他值为 json 对象
240
- */
241
- async getJson(key) {
242
- const conn = await this._getConnection();
243
- if (!conn) {
244
- return false;
245
- }
246
- const r = await conn.getJson(key, this._etc);
247
- conn.used();
248
- return r;
249
- }
250
- /**
251
- * --- 删除已存在的值 ---
252
- * @param keys
253
- */
254
- async del(keys) {
255
- const conn = await this._getConnection();
256
- if (!conn) {
257
- return false;
258
- }
259
- const r = await conn.del(keys, this._etc);
260
- conn.used();
261
- return r;
262
- }
263
- /**
264
- * --- 自增 ---
265
- * @param key
266
- * @param num 整数或浮点正数
267
- */
268
- async incr(key, num = 1) {
269
- const conn = await this._getConnection();
270
- if (!conn) {
271
- return false;
272
- }
273
- const r = await conn.incr(key, num, this._etc);
274
- conn.used();
275
- return r;
276
- }
277
- /**
278
- * --- 自减 ---
279
- * @param key
280
- * @param num 整数或浮点正数
281
- */
282
- async decr(key, num = 1) {
283
- const conn = await this._getConnection();
284
- if (!conn) {
285
- return false;
286
- }
287
- const r = await conn.decr(key, num, this._etc);
288
- conn.used();
289
- return r;
290
- }
291
- /**
292
- * --- 仅修改过期时间不修改值 ---
293
- * @param key
294
- * @param ttl
295
- */
296
- async expire(key, ttl) {
297
- const conn = await this._getConnection();
298
- if (!conn) {
299
- return false;
300
- }
301
- const r = await conn.expire(key, ttl, this._etc);
302
- conn.used();
303
- return r;
304
- }
305
- /**
306
- * --- 获取服务器上的所有 key 列表 ---
307
- * @param pattern
308
- */
309
- async keys(pattern) {
310
- const conn = await this._getConnection();
311
- if (!conn) {
312
- return false;
313
- }
314
- const r = await conn.keys(pattern, this._etc);
315
- conn.used();
316
- return r;
317
- }
318
- /**
319
- * --- 根据条件获取服务器上的 keys ---
320
- * @param cursor
321
- * @param pattern 例如 *
322
- * @param count 获取的条数
323
- */
324
- async scan(cursor = 0, pattern = '*', count = 10) {
325
- const conn = await this._getConnection();
326
- if (!conn) {
327
- return false;
328
- }
329
- const r = await conn.scan(cursor, pattern, count, this._etc);
330
- conn.used();
331
- return r;
332
- }
333
- /**
334
- * --- 清除当前所选数据库的所有内容 ---
335
- */
336
- async flushDb() {
337
- const conn = await this._getConnection();
338
- if (!conn) {
339
- return false;
340
- }
341
- const r = await conn.flushDb();
342
- conn.used();
343
- return r;
344
- }
345
- /**
346
- * --- 发送 ping ---
347
- */
348
- async ping() {
349
- const conn = await this._getConnection();
350
- if (!conn) {
351
- return false;
352
- }
353
- const r = await conn.ping();
354
- conn.used();
355
- return r;
356
- }
357
- /**
358
- * --- 设置哈希表值 ---
359
- * @param key key 名
360
- * @param field 字段名
361
- * @param val 值
362
- * @param mod 空,nx(key不存在才建立)
363
- */
364
- async hSet(key, field, val, mod = '') {
365
- const conn = await this._getConnection();
366
- if (!conn) {
367
- return false;
368
- }
369
- const r = await conn.hSet(key, field, val, mod, this._etc);
370
- conn.used();
371
- return r;
372
- }
373
- /**
374
- * --- 批量设置哈希值 ---
375
- * @param key key 名
376
- * @param rows key / val 数组
377
- */
378
- async hMSet(key, rows) {
379
- const conn = await this._getConnection();
380
- if (!conn) {
381
- return false;
382
- }
383
- const r = await conn.hMSet(key, rows, this._etc);
384
- conn.used();
385
- return r;
386
- }
387
- /**
388
- * --- 获取哈希值 ---
389
- * @param key
390
- * @param field
391
- */
392
- async hGet(key, field) {
393
- const conn = await this._getConnection();
394
- if (!conn) {
395
- return null;
396
- }
397
- const r = await conn.hGet(key, field, this._etc);
398
- conn.used();
399
- return r;
400
- }
401
- /**
402
- * --- 获取哈希 json 对象 ---
403
- * @param key
404
- * @param field
405
- */
406
- async hGetJson(key, field) {
407
- const conn = await this._getConnection();
408
- if (!conn) {
409
- return null;
410
- }
411
- const r = await conn.hGetJson(key, field, this._etc);
412
- conn.used();
413
- return r;
414
- }
415
- /**
416
- * --- 批量获取哈希值 ---
417
- * @param key
418
- * @param fields
419
- */
420
- async hMGet(key, fields) {
421
- const conn = await this._getConnection();
422
- if (conn) {
423
- const r = await conn.hMGet(key, fields, this._etc);
424
- conn.used();
425
- return r;
52
+ const configKv = ctr.getPrototype('_config').kv;
53
+ const user = etc?.user ?? configKv.user;
54
+ const pwd = etc?.pwd ?? configKv.pwd;
55
+ await this._link.auth(pwd, user || undefined);
56
+ await this._link.select(this._index);
57
+ return true;
426
58
  }
427
- else {
428
- const rtn = {};
429
- for (const field of fields) {
430
- rtn[field] = null;
59
+ catch {
60
+ // --- 初始化失败,移除 ---
61
+ const item = connections.findIndex(item => item.link === this._link);
62
+ if (item !== -1) {
63
+ connections.splice(item, 1);
431
64
  }
432
- return rtn;
433
- }
434
- }
435
- /**
436
- * --- 批量获取哈希键值对 ---
437
- * @param key
438
- */
439
- async hGetAll(key) {
440
- const conn = await this._getConnection();
441
- if (!conn) {
442
- return null;
443
- }
444
- const r = await conn.hGetAll(key, this._etc);
445
- conn.used();
446
- return r;
447
- }
448
- /**
449
- * --- 删除哈希键 ---
450
- * @param key
451
- * @param fields 值序列
452
- */
453
- async hDel(key, fields) {
454
- const conn = await this._getConnection();
455
- if (!conn) {
456
- return 0;
457
- }
458
- const r = await conn.hDel(key, fields, this._etc);
459
- conn.used();
460
- return r;
461
- }
462
- /**
463
- * --- 判断哈希字段是否存在 ---
464
- * @param key
465
- * @param field
466
- */
467
- async hExists(key, field) {
468
- const conn = await this._getConnection();
469
- if (!conn) {
470
65
  return false;
471
66
  }
472
- const r = await conn.hExists(key, field, this._etc);
473
- conn.used();
474
- return r;
475
- }
476
- /**
477
- * --- 设置哈希自增自减 ---
478
- * @param key key
479
- * @param field 字段
480
- * @param increment 正数或负数,整数或浮点
481
- */
482
- async hIncr(key, field, increment) {
483
- const conn = await this._getConnection();
484
- if (!conn) {
485
- return 0;
486
- }
487
- const r = await conn.hIncr(key, field, increment, this._etc);
488
- conn.used();
489
- return r;
490
- }
491
- /**
492
- * --- 获取哈希所有字段 ---
493
- * @param key
494
- */
495
- async hKeys(key) {
496
- const conn = await this._getConnection();
497
- if (!conn) {
498
- return [];
499
- }
500
- const r = await conn.hKeys(key, this._etc);
501
- conn.used();
502
- return r;
503
- }
504
- async lPush(key, values) {
505
- const conn = await this._getConnection();
506
- if (!conn) {
507
- return 0;
508
- }
509
- const r = await conn.lPush(key, values, this._etc);
510
- conn.used();
511
- return r;
512
- }
513
- async rPush(key, values) {
514
- const conn = await this._getConnection();
515
- if (!conn) {
516
- return 0;
517
- }
518
- const r = await conn.rPush(key, values, this._etc);
519
- conn.used();
520
- return r;
521
- }
522
- async bLMove(sourceKey, destKey, soo, deo, timeout) {
523
- const conn = await this._getConnection();
524
- if (!conn) {
525
- return null;
526
- }
527
- const r = await conn.bLMove(sourceKey, destKey, soo, deo, timeout, this._etc);
528
- conn.used();
529
- return r;
530
- }
531
- async lPop(key) {
532
- const conn = await this._getConnection();
533
- if (!conn) {
534
- return null;
535
- }
536
- const r = await conn.lPop(key, this._etc);
537
- conn.used();
538
- return r;
539
- }
540
- async rPop(key) {
541
- const conn = await this._getConnection();
542
- if (!conn) {
543
- return null;
544
- }
545
- const r = await conn.rPop(key, this._etc);
546
- conn.used();
547
- return r;
548
- }
549
- async bRPop(key, timeout) {
550
- const conn = await this._getConnection();
551
- if (!conn) {
552
- return {};
553
- }
554
- const r = await conn.bRPop(key, timeout, this._etc);
555
- conn.used();
556
- return r;
557
- }
558
- async lRange(key, start, stop) {
559
- const conn = await this._getConnection();
560
- if (!conn) {
561
- return [];
562
- }
563
- const r = await conn.lRange(key, start, stop, this._etc);
564
- conn.used();
565
- return r;
566
- }
567
- async lLen(key) {
568
- const conn = await this._getConnection();
569
- if (!conn) {
570
- return 0;
571
- }
572
- const r = await conn.lLen(key, this._etc);
573
- conn.used();
574
- return r;
575
- }
576
- /**
577
- * --- 从连接池获取一个连接,会被自动设置为使用中,需要在执行命令后解除占用 ---
578
- */
579
- async _getConnection() {
580
- let conn;
581
- for (const connection of connections) {
582
- const etc = connection.getEtc();
583
- if (connection.isLost() ||
584
- connection.isUsing() ||
585
- (etc.host !== this._etc.host) ||
586
- (etc.port !== this._etc.port) ||
587
- (etc.index !== this._etc.index)) {
588
- // --- 配置项连接项不匹配 ---
589
- continue;
590
- }
591
- connection.refreshLast();
592
- connection.setUsing();
593
- conn = connection;
594
- break;
595
- }
596
- if (!conn) {
597
- // --- 没有找到合适的连接,创建一个 ---
598
- const link = redis.createCommandClient({
599
- 'host': this._etc.host,
600
- 'port': this._etc.port,
601
- });
602
- // --- 开始连接 ---
603
- try {
604
- await link.connect();
605
- }
606
- catch {
607
- return null;
608
- }
609
- // --- 认证 ---
610
- if (this._etc.user || this._etc.pwd) {
611
- try {
612
- await link.auth(this._etc.user + this._etc.pwd);
613
- }
614
- catch {
615
- return null;
616
- }
617
- }
618
- await link.select(this._etc.index);
619
- conn = new Connection(this._etc, link);
620
- conn.refreshLast();
621
- conn.setUsing();
622
- link.on('error', function (err) {
623
- conn.setLost();
624
- // console.log(`--- redis [${conn._etc.host}:${conn._etc.port}] error ---`);
625
- lCore.debug('[KV][_getConnection][error]', err);
626
- }).on('end', () => {
627
- conn.setLost();
628
- }).on('close', () => {
629
- conn.setLost();
630
- });
631
- connections.push(conn);
632
- }
633
- return conn;
634
- }
635
- }
636
- export class Connection {
637
- constructor(etc, link) {
638
- /** --- 本连接最后一次使用时间 --- */
639
- this._last = 0;
640
- /** --- 当前连接是否正在被独占使用 --- */
641
- this._using = false;
642
- /** --- 当发生断开,则需从连接池移除连接 --- */
643
- this._lost = false;
644
- this._etc = etc;
645
- this._link = link;
646
- this.refreshLast();
647
- }
648
- /**
649
- * --- 获取连接 etc 信息 ---
650
- */
651
- getEtc() {
652
- return this._etc;
653
- }
654
- /**
655
- * --- 获取最后一次获取连接的时间 ---
656
- */
657
- getLast() {
658
- return this._last;
659
- }
660
- /**
661
- * --- 将本条连接设置为不可用 ---
662
- */
663
- setLost() {
664
- this._lost = true;
665
- }
666
- /**
667
- * --- 是否已经丢失 ---
668
- */
669
- isLost() {
670
- return this._lost;
671
- }
672
- /**
673
- * --- 将本条连接设置占用中 ---
674
- */
675
- setUsing() {
676
- this._using = true;
677
- }
678
- /**
679
- * --- 获取当前状态是否正在被使用中 ---
680
- */
681
- isUsing() {
682
- return this._using;
683
- }
684
- /**
685
- * --- 取消占用 ---
686
- */
687
- used() {
688
- this._using = false;
689
- }
690
- /**
691
- * --- 设定最后使用时间 ---
692
- */
693
- refreshLast() {
694
- this._last = lTime.stamp();
695
- }
696
- /**
697
- * --- 断开此连接,一般情况下不使用 ---
698
- */
699
- async end() {
700
- try {
701
- await this._link.close();
702
- }
703
- catch {
704
- return;
705
- }
706
67
  }
707
68
  /**
708
69
  * --- 设定一个值 ---
@@ -710,23 +71,21 @@ export class Connection {
710
71
  * @param val
711
72
  * @param ttl 秒,0 为不限制
712
73
  * @param mod 设置模式: 空,nx(key不存在才建立),xx(key存在才修改)
713
- * @param etc 配置项,主要用 etc.pre
714
74
  */
715
- async set(key, val, ttl, mod, etc) {
716
- this.refreshLast();
75
+ async set(key, val, ttl = 0, mod = '') {
717
76
  if (typeof val !== 'string') {
718
77
  val = lText.stringifyJson(val);
719
78
  }
720
79
  try {
721
80
  switch (mod) {
722
81
  case '': {
723
- return await this._link.set(etc.pre + key, val, ttl === 0 ? undefined : ttl);
82
+ return await this._link.set(this._pre + key, val, ttl === 0 ? undefined : ttl);
724
83
  }
725
84
  case 'nx': {
726
- return await this._link.setNX(etc.pre + key, val, ttl === 0 ? undefined : ttl);
85
+ return await this._link.setNX(this._pre + key, val, ttl === 0 ? undefined : ttl);
727
86
  }
728
87
  case 'xx': {
729
- return await this._link.replace(etc.pre + key, val, ttl === 0 ? undefined : ttl);
88
+ return await this._link.replace(this._pre + key, val, ttl === 0 ? undefined : ttl);
730
89
  }
731
90
  }
732
91
  }
@@ -739,10 +98,9 @@ export class Connection {
739
98
  * @param key
740
99
  * @param val
741
100
  * @param ttl 秒,0 为不限制
742
- * @param etc
743
101
  */
744
- async add(key, val, ttl, etc) {
745
- return this.set(key, val, ttl, 'nx', etc);
102
+ async add(key, val, ttl = 0) {
103
+ return this.set(key, val, ttl, 'nx');
746
104
  }
747
105
  /**
748
106
  * --- 替换一个存在的值 ---
@@ -751,19 +109,17 @@ export class Connection {
751
109
  * @param ttl 秒,0 为不限制
752
110
  * @param etc
753
111
  */
754
- async replace(key, val, ttl, etc) {
755
- return this.set(key, val, ttl, 'xx', etc);
112
+ async replace(key, val, ttl = 0) {
113
+ return this.set(key, val, ttl, 'xx');
756
114
  }
757
115
  /**
758
116
  * --- 向已存在的值后追加数据 ---
759
117
  * @param key
760
118
  * @param val
761
- * @param etc
762
119
  */
763
- async append(key, val, etc) {
764
- this.refreshLast();
120
+ async append(key, val) {
765
121
  try {
766
- return await this._link.append(etc.pre + key, val) > 0 ? true : false;
122
+ return await this._link.append(this._pre + key, val) > 0 ? true : false;
767
123
  }
768
124
  catch {
769
125
  return false;
@@ -774,8 +130,7 @@ export class Connection {
774
130
  * @param key
775
131
  * @param val
776
132
  */
777
- async prepend(key, val, etc) {
778
- this.refreshLast();
133
+ async prepend(key, val) {
779
134
  try {
780
135
  const script = `local val = redis.call('GET', KEYS[1])
781
136
  if (val == false) then
@@ -787,11 +142,11 @@ if (r) then
787
142
  else
788
143
  return 0
789
144
  end`;
790
- let r = await this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [etc.pre + key], [val]);
145
+ let r = await this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [this._pre + key], [val]);
791
146
  r = parseInt(r);
792
147
  if (r <= 0) {
793
148
  await this._link.scriptLoad(script);
794
- r = this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [etc.pre + key], [val]);
149
+ r = await this._link.evalSHA('ea360f3f6508a243824ecda6be15db56df217873', [this._pre + key], [val]);
795
150
  r = parseInt(r);
796
151
  }
797
152
  return r > 0 ? true : false;
@@ -803,16 +158,14 @@ end`;
803
158
  /**
804
159
  * --- 检测 key 是否存在 ---
805
160
  * @param keys 单个或序列
806
- * @param etc
807
161
  */
808
- async exists(keys, etc) {
809
- this.refreshLast();
162
+ async exists(keys) {
810
163
  try {
811
164
  if (typeof keys === 'string') {
812
165
  keys = [keys];
813
166
  }
814
167
  for (let k = 0; k < keys.length; ++k) {
815
- keys[k] = etc.pre + keys[k];
168
+ keys[k] = this._pre + keys[k];
816
169
  }
817
170
  return await this._link.mExists(keys);
818
171
  }
@@ -823,13 +176,11 @@ end`;
823
176
  /**
824
177
  * --- 获取字符串 ---
825
178
  * @param key
826
- * @param etc
827
179
  * @returns 字符串 / false / null(即使存入时是 number,这个方法也只会返回字符串)
828
180
  */
829
- async get(key, etc) {
830
- this.refreshLast();
181
+ async get(key) {
831
182
  try {
832
- return await this._link.get(etc.pre + key);
183
+ return await this._link.get(this._pre + key);
833
184
  }
834
185
  catch {
835
186
  return false;
@@ -838,12 +189,10 @@ end`;
838
189
  /**
839
190
  * --- 获取相应的剩余有效期秒数 ---
840
191
  * @param key
841
- * @param etc
842
192
  */
843
- async ttl(key, etc) {
844
- this.refreshLast();
193
+ async ttl(key) {
845
194
  try {
846
- return await this._link.ttl(etc.pre + key);
195
+ return await this._link.ttl(this._pre + key);
847
196
  }
848
197
  catch {
849
198
  return null;
@@ -852,12 +201,10 @@ end`;
852
201
  /**
853
202
  * --- 获取相应的剩余有效期毫秒数 ---
854
203
  * @param key
855
- * @param etc
856
204
  */
857
- async pttl(key, etc) {
858
- this.refreshLast();
205
+ async pttl(key) {
859
206
  try {
860
- return await this._link.pTTL(etc.pre + key);
207
+ return await this._link.pTTL(this._pre + key);
861
208
  }
862
209
  catch {
863
210
  return null;
@@ -866,16 +213,14 @@ end`;
866
213
  /**
867
214
  * --- 批量获取值 ---
868
215
  * @param keys key 序列
869
- * @param etc 顺序数组
870
216
  */
871
- async mGet(keys, etc) {
872
- this.refreshLast();
217
+ async mGet(keys) {
873
218
  for (let k = 0; k < keys.length; ++k) {
874
- keys[k] = etc.pre + keys[k];
219
+ keys[k] = this._pre + keys[k];
875
220
  }
876
221
  const rtn = {};
877
222
  try {
878
- const pl = etc.pre.length;
223
+ const pl = this._pre.length;
879
224
  const r = await this._link.mGet(keys);
880
225
  if (pl === 0) {
881
226
  return r;
@@ -897,12 +242,11 @@ end`;
897
242
  * @param rows key / val 数组
898
243
  * @param etc
899
244
  */
900
- async mSet(rows, etc) {
901
- this.refreshLast();
245
+ async mSet(rows) {
902
246
  try {
903
247
  const rtn = {};
904
248
  for (const key in rows) {
905
- rtn[etc.pre + key] = rows[key];
249
+ rtn[this._pre + key] = rows[key];
906
250
  }
907
251
  await this._link.mSet(rtn);
908
252
  return true;
@@ -914,10 +258,9 @@ end`;
914
258
  /**
915
259
  * --- 获取 json 对象 ---
916
260
  * @param key
917
- * @param etc
918
261
  */
919
- async getJson(key, etc) {
920
- const v = await this.get(key, etc);
262
+ async getJson(key) {
263
+ const v = await this.get(key);
921
264
  if (v === null || v === false) {
922
265
  return v;
923
266
  }
@@ -927,15 +270,13 @@ end`;
927
270
  /**
928
271
  * --- 删除已存在的值 ---
929
272
  * @param keys
930
- * @param etc
931
273
  */
932
- async del(keys, etc) {
933
- this.refreshLast();
274
+ async del(keys) {
934
275
  if (typeof keys === 'string') {
935
276
  keys = [keys];
936
277
  }
937
278
  for (let k = 0; k < keys.length; ++k) {
938
- keys[k] = etc.pre + keys[k];
279
+ keys[k] = this._pre + keys[k];
939
280
  }
940
281
  try {
941
282
  return await this._link.del(keys) > 0 ? true : false;
@@ -948,21 +289,19 @@ end`;
948
289
  * --- 自增 ---
949
290
  * @param key
950
291
  * @param num 整数或浮点正数
951
- * @param etc
952
292
  */
953
- async incr(key, num, etc) {
954
- this.refreshLast();
293
+ async incr(key, num = 1) {
955
294
  try {
956
295
  if (Number.isInteger(num)) {
957
296
  if (num === 1) {
958
- return await this._link.incr(etc.pre + key);
297
+ return await this._link.incr(this._pre + key);
959
298
  }
960
299
  else {
961
- return await this._link.incr(etc.pre + key, num);
300
+ return await this._link.incr(this._pre + key, num);
962
301
  }
963
302
  }
964
303
  else {
965
- return await this._link.incrByFloat(etc.pre + key, num);
304
+ return await this._link.incrByFloat(this._pre + key, num);
966
305
  }
967
306
  }
968
307
  catch {
@@ -973,21 +312,19 @@ end`;
973
312
  * --- 自减 ---
974
313
  * @param key
975
314
  * @param num 整数或浮点正数
976
- * @param etc
977
315
  */
978
- async decr(key, num, etc) {
979
- this.refreshLast();
316
+ async decr(key, num = 1) {
980
317
  try {
981
318
  if (Number.isInteger(num)) {
982
319
  if (num === 1) {
983
- return await this._link.decr(etc.pre + key);
320
+ return await this._link.decr(this._pre + key);
984
321
  }
985
322
  else {
986
- return await this._link.decr(etc.pre + key, num);
323
+ return await this._link.decr(this._pre + key, num);
987
324
  }
988
325
  }
989
326
  else {
990
- return await this._link.incrByFloat(etc.pre + key, -num);
327
+ return await this._link.incrByFloat(this._pre + key, -num);
991
328
  }
992
329
  }
993
330
  catch {
@@ -998,12 +335,10 @@ end`;
998
335
  * --- 仅修改过期时间不修改值 ---
999
336
  * @param key
1000
337
  * @param ttl
1001
- * @param etc
1002
338
  */
1003
- async expire(key, ttl, etc) {
1004
- this.refreshLast();
339
+ async expire(key, ttl) {
1005
340
  try {
1006
- return await this._link.expire(etc.pre + key, ttl);
341
+ return await this._link.expire(this._pre + key, ttl);
1007
342
  }
1008
343
  catch {
1009
344
  return false;
@@ -1013,11 +348,10 @@ end`;
1013
348
  * --- 获取服务器上的所有 key 列表 ---
1014
349
  * @param pattern
1015
350
  */
1016
- async keys(pattern, etc) {
1017
- this.refreshLast();
351
+ async keys(pattern) {
1018
352
  try {
1019
- const r = await this._link.keys(etc.pre + pattern);
1020
- const pl = etc.pre.length;
353
+ const r = await this._link.keys(this._pre + pattern);
354
+ const pl = this._pre.length;
1021
355
  if (pl > 0) {
1022
356
  for (let k = 0; k < r.length; ++k) {
1023
357
  r[k] = r[k].slice(pl);
@@ -1034,14 +368,12 @@ end`;
1034
368
  * @param cursor
1035
369
  * @param pattern 例如 *
1036
370
  * @param count 获取的条数
1037
- * @param etc
1038
371
  */
1039
- async scan(cursor, pattern, count, etc) {
1040
- this.refreshLast();
372
+ async scan(cursor = 0, pattern = '*', count = 10) {
1041
373
  try {
1042
- const r = await this._link.scan(cursor, etc.pre + pattern, count);
374
+ const r = await this._link.scan(cursor, this._pre + pattern, count);
1043
375
  for (let i = 0; i < r.items.length; ++i) {
1044
- r.items[i] = r.items[i].slice(this._etc.pre.length);
376
+ r.items[i] = r.items[i].slice(this._pre.length);
1045
377
  }
1046
378
  return r;
1047
379
  }
@@ -1053,7 +385,6 @@ end`;
1053
385
  * --- 清除当前所选数据库的所有内容 ---
1054
386
  */
1055
387
  async flushDb() {
1056
- this.refreshLast();
1057
388
  try {
1058
389
  await this._link.flushDb();
1059
390
  return true;
@@ -1066,10 +397,7 @@ end`;
1066
397
  * --- 发送 ping ---
1067
398
  * @param last 是否刷新最后使用时间(默认刷新)
1068
399
  */
1069
- async ping(last = true) {
1070
- if (last) {
1071
- this.refreshLast();
1072
- }
400
+ async ping() {
1073
401
  try {
1074
402
  return (await this._link.ping()) === 'PONG' ? 'PONG' : false;
1075
403
  }
@@ -1083,19 +411,17 @@ end`;
1083
411
  * @param field 字段名
1084
412
  * @param val 值
1085
413
  * @param mod 空,nx(key不存在才建立)
1086
- * @param etc
1087
414
  */
1088
- async hSet(key, field, val, mod, etc) {
1089
- this.refreshLast();
415
+ async hSet(key, field, val, mod = '') {
1090
416
  try {
1091
417
  if (typeof val !== 'string') {
1092
418
  val = lText.stringifyJson(val);
1093
419
  }
1094
420
  if (mod === 'nx') {
1095
- return await this._link.hSetNX(etc.pre + key, field, val);
421
+ return await this._link.hSetNX(this._pre + key, field, val);
1096
422
  }
1097
423
  else {
1098
- return await this._link.hSet(etc.pre + key, field, val);
424
+ return await this._link.hSet(this._pre + key, field, val);
1099
425
  }
1100
426
  }
1101
427
  catch {
@@ -1106,10 +432,8 @@ end`;
1106
432
  * --- 批量设置哈希值 ---
1107
433
  * @param key key 名
1108
434
  * @param rows key / val 数组
1109
- * @param etc
1110
435
  */
1111
- async hMSet(key, rows, etc) {
1112
- this.refreshLast();
436
+ async hMSet(key, rows) {
1113
437
  try {
1114
438
  for (const i in rows) {
1115
439
  const val = rows[i];
@@ -1117,7 +441,7 @@ end`;
1117
441
  rows[i] = lText.stringifyJson(val);
1118
442
  }
1119
443
  }
1120
- await this._link.hMSet(etc.pre + key, rows);
444
+ await this._link.hMSet(this._pre + key, rows);
1121
445
  return true;
1122
446
  }
1123
447
  catch {
@@ -1128,12 +452,10 @@ end`;
1128
452
  * --- 获取哈希值 ---
1129
453
  * @param key
1130
454
  * @param field
1131
- * @param etc
1132
455
  */
1133
- async hGet(key, field, etc) {
1134
- this.refreshLast();
456
+ async hGet(key, field) {
1135
457
  try {
1136
- return await this._link.hGet(etc.pre + key, field);
458
+ return await this._link.hGet(this._pre + key, field);
1137
459
  }
1138
460
  catch {
1139
461
  return null;
@@ -1143,10 +465,9 @@ end`;
1143
465
  * --- 获取哈希 json 对象 ---
1144
466
  * @param key
1145
467
  * @param field
1146
- * @param etc
1147
468
  */
1148
- async hGetJson(key, field, etc) {
1149
- const v = await this.hGet(key, field, etc);
469
+ async hGetJson(key, field) {
470
+ const v = await this.hGet(key, field);
1150
471
  if (v === null) {
1151
472
  return null;
1152
473
  }
@@ -1157,12 +478,10 @@ end`;
1157
478
  * --- 批量获取哈希值 ---
1158
479
  * @param key
1159
480
  * @param fields
1160
- * @param etc
1161
481
  */
1162
- async hMGet(key, fields, etc) {
1163
- this.refreshLast();
482
+ async hMGet(key, fields) {
1164
483
  try {
1165
- return await this._link.hMGet(etc.pre + key, fields);
484
+ return await this._link.hMGet(this._pre + key, fields);
1166
485
  }
1167
486
  catch {
1168
487
  const rtn = {};
@@ -1175,12 +494,10 @@ end`;
1175
494
  /**
1176
495
  * --- 批量获取哈希键值对 ---
1177
496
  * @param key
1178
- * @param etc
1179
497
  */
1180
- async hGetAll(key, etc) {
1181
- this.refreshLast();
498
+ async hGetAll(key) {
1182
499
  try {
1183
- return await this._link.hGetAll(etc.pre + key);
500
+ return await this._link.hGetAll(this._pre + key);
1184
501
  }
1185
502
  catch {
1186
503
  return null;
@@ -1190,12 +507,10 @@ end`;
1190
507
  * --- 删除哈希键 ---
1191
508
  * @param key
1192
509
  * @param fields 值序列
1193
- * @param etc
1194
510
  */
1195
- async hDel(key, fields, etc) {
1196
- this.refreshLast();
511
+ async hDel(key, fields) {
1197
512
  try {
1198
- return await this._link.hDel(etc.pre + key, fields);
513
+ return await this._link.hDel(this._pre + key, fields);
1199
514
  }
1200
515
  catch {
1201
516
  return 0;
@@ -1205,12 +520,10 @@ end`;
1205
520
  * --- 判断哈希字段是否存在 ---
1206
521
  * @param key
1207
522
  * @param field
1208
- * @param etc
1209
523
  */
1210
- async hExists(key, field, etc) {
1211
- this.refreshLast();
524
+ async hExists(key, field) {
1212
525
  try {
1213
- return await this._link.hExists(etc.pre + key, field);
526
+ return await this._link.hExists(this._pre + key, field);
1214
527
  }
1215
528
  catch {
1216
529
  return false;
@@ -1221,16 +534,14 @@ end`;
1221
534
  * @param key key
1222
535
  * @param field 字段
1223
536
  * @param increment 正数或负数,整数或浮点
1224
- * @param etc
1225
537
  */
1226
- async hIncr(key, field, increment, etc) {
1227
- this.refreshLast();
538
+ async hIncr(key, field, increment) {
1228
539
  try {
1229
540
  if (Number.isInteger(increment)) {
1230
- return await this._link.hIncr(etc.pre + key, field, increment);
541
+ return await this._link.hIncr(this._pre + key, field, increment);
1231
542
  }
1232
543
  else {
1233
- return await this._link.hIncrByFloat(etc.pre + key, field, increment);
544
+ return await this._link.hIncrByFloat(this._pre + key, field, increment);
1234
545
  }
1235
546
  }
1236
547
  catch {
@@ -1240,87 +551,77 @@ end`;
1240
551
  /**
1241
552
  * --- 获取哈希所有字段 ---
1242
553
  * @param key
1243
- * @param etc
1244
554
  */
1245
- async hKeys(key, etc) {
1246
- this.refreshLast();
555
+ async hKeys(key) {
1247
556
  try {
1248
- return await this._link.hKeys(etc.pre + key);
557
+ return await this._link.hKeys(this._pre + key);
1249
558
  }
1250
559
  catch {
1251
560
  return [];
1252
561
  }
1253
562
  }
1254
- async lPush(key, values, etc) {
1255
- this.refreshLast();
563
+ async lPush(key, values) {
1256
564
  try {
1257
- return await this._link.lPush(etc.pre + key, values);
565
+ return await this._link.lPush(this._pre + key, values);
1258
566
  }
1259
567
  catch {
1260
568
  return 0;
1261
569
  }
1262
570
  }
1263
- async rPush(key, values, etc) {
1264
- this.refreshLast();
571
+ async rPush(key, values) {
1265
572
  try {
1266
- return await this._link.rPush(etc.pre + key, values);
573
+ return await this._link.rPush(this._pre + key, values);
1267
574
  }
1268
575
  catch {
1269
576
  return 0;
1270
577
  }
1271
578
  }
1272
- async bLMove(sourceKey, destKey, soo, deo, timeout, etc) {
1273
- this.refreshLast();
579
+ async bLMove(sourceKey, destKey, soo, deo, timeout) {
1274
580
  try {
1275
- return await this._link.bLMove(etc.pre + sourceKey, etc.pre + destKey, soo, deo, timeout);
581
+ return await this._link.bLMove(this._pre + sourceKey, this._pre + destKey, soo, deo, timeout);
1276
582
  }
1277
583
  catch {
1278
584
  return null;
1279
585
  }
1280
586
  }
1281
- async lPop(key, etc) {
1282
- this.refreshLast();
587
+ async lPop(key) {
1283
588
  try {
1284
- return await this._link.lPop(etc.pre + key);
589
+ return await this._link.lPop(this._pre + key);
1285
590
  }
1286
591
  catch {
1287
592
  return null;
1288
593
  }
1289
594
  }
1290
- async rPop(key, etc) {
1291
- this.refreshLast();
595
+ async rPop(key) {
1292
596
  try {
1293
- return await this._link.rPop(etc.pre + key);
597
+ return await this._link.rPop(this._pre + key);
1294
598
  }
1295
599
  catch {
1296
600
  return null;
1297
601
  }
1298
602
  }
1299
- async bRPop(key, timeout, etc) {
1300
- this.refreshLast();
603
+ async bRPop(key, timeout) {
1301
604
  try {
1302
605
  if (typeof key === 'string') {
1303
606
  key = [key];
1304
607
  }
1305
- return await this._link.bRPop(key.map(item => etc.pre + item), timeout);
608
+ return await this._link.bRPop(key.map(item => this._pre + item), timeout);
1306
609
  }
1307
610
  catch {
1308
611
  return {};
1309
612
  }
1310
613
  }
1311
- async lRange(key, start, stop, etc) {
1312
- this.refreshLast();
614
+ async lRange(key, start, stop) {
1313
615
  try {
1314
- return await this._link.lRange(etc.pre + key, start, stop);
616
+ return await this._link.lRange(this._pre + key, start, stop);
1315
617
  }
1316
618
  catch {
1317
619
  return [];
1318
620
  }
1319
621
  }
1320
- async lLen(key, etc) {
1321
- this.refreshLast();
622
+ async lLen(key) {
1322
623
  try {
1323
- return await this._link.lLen(etc.pre + key);
624
+ return await this._link.lLen(this._pre + key);
1324
625
  }
1325
626
  catch {
1326
627
  return 0;
@@ -1328,30 +629,12 @@ end`;
1328
629
  }
1329
630
  }
1330
631
  /**
1331
- * --- 获取 Kv Pool 对象 ---
632
+ * --- 获取 Kv 对象 ---
1332
633
  * @param etc 配置信息可留空
1333
634
  */
1334
- export function get(ctr, etc) {
635
+ export async function get(ctr, etc) {
1335
636
  etc ??= ctr.getPrototype('_config').kv;
1336
- return new Pool(ctr, etc);
1337
- }
1338
- /**
1339
- * --- 获取当前连接池中所有连接的信息 ---
1340
- */
1341
- export function getConnectionList() {
1342
- const list = [];
1343
- for (let i = 0; i < connections.length; ++i) {
1344
- const connection = connections[i];
1345
- const etc = connection.getEtc();
1346
- list.push({
1347
- 'id': i,
1348
- 'last': connection.getLast(),
1349
- 'host': etc.host,
1350
- 'port': etc.port,
1351
- 'index': etc.index,
1352
- 'lost': connection.isLost(),
1353
- 'using': connection.isUsing()
1354
- });
1355
- }
1356
- return list;
637
+ const kv = new Kv(ctr, etc);
638
+ const r = await kv.init(ctr, etc);
639
+ return r ? kv : false;
1357
640
  }