befly 3.17.8 → 3.17.10

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.
@@ -12,8 +12,6 @@ import { isFiniteNumber, isNonEmptyString, isString } from "../utils/is.js";
12
12
  * 约定:除构造函数外,方法默认不抛异常;失败时返回 null/false/0/[] 并记录日志。
13
13
  */
14
14
  export class RedisHelper {
15
- slowThresholdMs = 500;
16
-
17
15
  /**
18
16
  * 构造函数
19
17
  * @param prefix - Key 前缀
@@ -30,18 +28,6 @@ export class RedisHelper {
30
28
  this.prefix = prefix ? `${prefix}:` : "";
31
29
  }
32
30
 
33
- logSlow(cmd, key, duration, extra = {}) {
34
- if (duration <= this.slowThresholdMs) return;
35
- Logger.warn("🐌 Redis 慢操作", {
36
- subsystem: "redis",
37
- event: "slow",
38
- duration: duration,
39
- cmd: cmd,
40
- key: key,
41
- extra: extra
42
- });
43
- }
44
-
45
31
  /**
46
32
  * 设置对象到 Redis
47
33
  * @param key - 键名
@@ -54,19 +40,11 @@ export class RedisHelper {
54
40
  const data = JSON.stringify(obj);
55
41
  const pkey = `${this.prefix}${key}`;
56
42
 
57
- const startTime = Date.now();
58
-
59
43
  if (ttl) {
60
- const res = await this.client.setex(pkey, ttl, data);
61
- const duration = Date.now() - startTime;
62
- this.logSlow("SETEX", pkey, duration, { ttl: ttl });
63
- return res;
44
+ return await this.client.setex(pkey, ttl, data);
64
45
  }
65
46
 
66
- const res = await this.client.set(pkey, data);
67
- const duration = Date.now() - startTime;
68
- this.logSlow("SET", pkey, duration);
69
- return res;
47
+ return await this.client.set(pkey, data);
70
48
  } catch (error) {
71
49
  Logger.error("Redis setObject 错误", error);
72
50
  return null;
@@ -81,11 +59,7 @@ export class RedisHelper {
81
59
  async getObject(key) {
82
60
  try {
83
61
  const pkey = `${this.prefix}${key}`;
84
-
85
- const startTime = Date.now();
86
62
  const data = await this.client.get(pkey);
87
- const duration = Date.now() - startTime;
88
- this.logSlow("GET", pkey, duration);
89
63
  return data ? JSON.parse(data) : null;
90
64
  } catch (error) {
91
65
  Logger.error("Redis getObject 错误", error);
@@ -100,11 +74,7 @@ export class RedisHelper {
100
74
  async delObject(key) {
101
75
  try {
102
76
  const pkey = `${this.prefix}${key}`;
103
-
104
- const startTime = Date.now();
105
77
  await this.client.del(pkey);
106
- const duration = Date.now() - startTime;
107
- this.logSlow("DEL", pkey, duration);
108
78
  } catch (error) {
109
79
  Logger.error("Redis delObject 错误", error);
110
80
  }
@@ -124,16 +94,11 @@ export class RedisHelper {
124
94
  const timestamp = Date.now();
125
95
  const key = `${this.prefix}time_id:${timestamp}`;
126
96
 
127
- const startTime = Date.now();
128
-
129
97
  const counter = await this.client.incr(key);
130
98
  if (counter === 1) {
131
99
  await this.client.expire(key, 1);
132
100
  }
133
101
 
134
- const duration = Date.now() - startTime;
135
- this.logSlow("INCR", key, duration, { expireSeconds: 1 });
136
-
137
102
  // 基于时间戳偏移起点,后缀 100-999 循环
138
103
  const suffix = 100 + (((timestamp % 900) + counter - 1) % 900);
139
104
 
@@ -150,104 +115,17 @@ export class RedisHelper {
150
115
  async setString(key, value, ttl = null) {
151
116
  try {
152
117
  const pkey = `${this.prefix}${key}`;
153
-
154
- const startTime = Date.now();
155
118
  if (ttl) {
156
- const res = await this.client.setex(pkey, ttl, value);
157
- const duration = Date.now() - startTime;
158
- this.logSlow("SETEX", pkey, duration, { ttl: ttl });
159
- return res;
119
+ return await this.client.setex(pkey, ttl, value);
160
120
  }
161
121
 
162
- const res = await this.client.set(pkey, value);
163
- const duration = Date.now() - startTime;
164
- this.logSlow("SET", pkey, duration);
165
- return res;
122
+ return await this.client.set(pkey, value);
166
123
  } catch (error) {
167
124
  Logger.error("Redis setString 错误", error);
168
125
  return null;
169
126
  }
170
127
  }
171
128
 
172
- /**
173
- * 尝试获取分布式锁(SET key token NX PX ttlMs)
174
- */
175
- async tryAcquireLock(key, token, ttlMs) {
176
- try {
177
- if (!isNonEmptyString(key)) {
178
- throw new Error("tryAcquireLock: key 必须是非空字符串", {
179
- cause: null,
180
- code: "validation"
181
- });
182
- }
183
- if (!isNonEmptyString(token)) {
184
- throw new Error("tryAcquireLock: token 必须是非空字符串", {
185
- cause: null,
186
- code: "validation"
187
- });
188
- }
189
- if (!(isFiniteNumber(ttlMs) && ttlMs > 0)) {
190
- throw new Error("tryAcquireLock: ttlMs 必须是正数", {
191
- cause: null,
192
- code: "validation"
193
- });
194
- }
195
-
196
- const pkey = `${this.prefix}${key}`;
197
- const startTime = Date.now();
198
- const ttlMsString = String(Math.floor(ttlMs));
199
- const res = await this.client.set(pkey, token, "NX", "PX", ttlMsString);
200
- const duration = Date.now() - startTime;
201
- this.logSlow("SET NX PX", pkey, duration, { ttlMs: ttlMs });
202
-
203
- return res === "OK";
204
- } catch (error) {
205
- Logger.error("Redis tryAcquireLock 错误", error);
206
- return false;
207
- }
208
- }
209
-
210
- /**
211
- * 释放分布式锁(原子校验 token 后删除)
212
- */
213
- async releaseLock(key, token) {
214
- try {
215
- if (!isNonEmptyString(key)) {
216
- throw new Error("releaseLock: key 必须是非空字符串", {
217
- cause: null,
218
- code: "validation"
219
- });
220
- }
221
- if (!isNonEmptyString(token)) {
222
- throw new Error("releaseLock: token 必须是非空字符串", {
223
- cause: null,
224
- code: "validation"
225
- });
226
- }
227
-
228
- const pkey = `${this.prefix}${key}`;
229
-
230
- // 注意:Bun.RedisClient 当前未暴露 Lua/EVAL 等原子 compare-and-del API。
231
- // 这里使用 get + del 的最小窗口实现;理论上存在极端竞态(TTL 恰好过期并被他人抢占)。
232
- // 对启动期同步场景来说风险可接受;同时锁本身带 TTL,最坏情况下依赖 TTL 自动释放。
233
- const startTime = Date.now();
234
-
235
- const current = await this.client.get(pkey);
236
- if (current !== token) {
237
- return false;
238
- }
239
-
240
- const deleted = await this.client.del(pkey);
241
- const duration = Date.now() - startTime;
242
- this.logSlow("GET+DEL", pkey, duration);
243
-
244
- return deleted > 0;
245
- } catch (error) {
246
- Logger.error("Redis releaseLock 错误", error);
247
- return false;
248
- }
249
- }
250
-
251
129
  /**
252
130
  * 获取字符串值
253
131
  * @param key - 键名
@@ -255,12 +133,7 @@ export class RedisHelper {
255
133
  async getString(key) {
256
134
  try {
257
135
  const pkey = `${this.prefix}${key}`;
258
-
259
- const startTime = Date.now();
260
- const res = await this.client.get(pkey);
261
- const duration = Date.now() - startTime;
262
- this.logSlow("GET", pkey, duration);
263
- return res;
136
+ return await this.client.get(pkey);
264
137
  } catch (error) {
265
138
  Logger.error("Redis getString 错误", error);
266
139
  return null;
@@ -275,12 +148,7 @@ export class RedisHelper {
275
148
  async exists(key) {
276
149
  try {
277
150
  const pkey = `${this.prefix}${key}`;
278
-
279
- const startTime = Date.now();
280
- const res = await this.client.exists(pkey);
281
- const duration = Date.now() - startTime;
282
- this.logSlow("EXISTS", pkey, duration);
283
- return res;
151
+ return await this.client.exists(pkey);
284
152
  } catch (error) {
285
153
  Logger.error("Redis exists 错误", error);
286
154
  return false;
@@ -295,12 +163,7 @@ export class RedisHelper {
295
163
  async incr(key) {
296
164
  try {
297
165
  const pkey = `${this.prefix}${key}`;
298
-
299
- const startTime = Date.now();
300
- const res = await this.client.incr(pkey);
301
- const duration = Date.now() - startTime;
302
- this.logSlow("INCR", pkey, duration);
303
- return res;
166
+ return await this.client.incr(pkey);
304
167
  } catch (error) {
305
168
  Logger.error("Redis incr 错误", error);
306
169
  return 0;
@@ -316,14 +179,10 @@ export class RedisHelper {
316
179
  async incrWithExpire(key, seconds) {
317
180
  try {
318
181
  const pkey = `${this.prefix}${key}`;
319
-
320
- const startTime = Date.now();
321
182
  const res = await this.client.incr(pkey);
322
183
  if (res === 1) {
323
184
  await this.client.expire(pkey, seconds);
324
185
  }
325
- const duration = Date.now() - startTime;
326
- this.logSlow("INCR", pkey, duration, { expireSeconds: seconds });
327
186
  return res;
328
187
  } catch (error) {
329
188
  Logger.error("Redis incrWithExpire 错误", error);
@@ -339,12 +198,7 @@ export class RedisHelper {
339
198
  async expire(key, seconds) {
340
199
  try {
341
200
  const pkey = `${this.prefix}${key}`;
342
-
343
- const startTime = Date.now();
344
- const res = await this.client.expire(pkey, seconds);
345
- const duration = Date.now() - startTime;
346
- this.logSlow("EXPIRE", pkey, duration, { seconds: seconds });
347
- return res;
201
+ return await this.client.expire(pkey, seconds);
348
202
  } catch (error) {
349
203
  Logger.error("Redis expire 错误", error);
350
204
  return 0;
@@ -358,12 +212,7 @@ export class RedisHelper {
358
212
  async ttl(key) {
359
213
  try {
360
214
  const pkey = `${this.prefix}${key}`;
361
-
362
- const startTime = Date.now();
363
- const res = await this.client.ttl(pkey);
364
- const duration = Date.now() - startTime;
365
- this.logSlow("TTL", pkey, duration);
366
- return res;
215
+ return await this.client.ttl(pkey);
367
216
  } catch (error) {
368
217
  Logger.error("Redis ttl 错误", error);
369
218
  return -1;
@@ -400,18 +249,11 @@ export class RedisHelper {
400
249
  if (members.length === 0) return 0;
401
250
 
402
251
  const pkey = `${this.prefix}${key}`;
403
-
404
- const startTime = Date.now();
405
252
  const args = [pkey];
406
253
  for (const member of members) {
407
254
  args.push(member);
408
255
  }
409
- const res = await this.client.sadd.apply(this.client, args);
410
- const duration = Date.now() - startTime;
411
- this.logSlow("SADD", pkey, duration, {
412
- membersCount: members.length
413
- });
414
- return res;
256
+ return await this.client.sadd.apply(this.client, args);
415
257
  } catch (error) {
416
258
  Logger.error("Redis sadd 错误", error);
417
259
  return 0;
@@ -427,12 +269,7 @@ export class RedisHelper {
427
269
  async sismember(key, member) {
428
270
  try {
429
271
  const pkey = `${this.prefix}${key}`;
430
-
431
- const startTime = Date.now();
432
- const res = await this.client.sismember(pkey, member);
433
- const duration = Date.now() - startTime;
434
- this.logSlow("SISMEMBER", pkey, duration);
435
- return res;
272
+ return await this.client.sismember(pkey, member);
436
273
  } catch (error) {
437
274
  Logger.error("Redis sismember 错误", error);
438
275
  return false;
@@ -447,12 +284,7 @@ export class RedisHelper {
447
284
  async scard(key) {
448
285
  try {
449
286
  const pkey = `${this.prefix}${key}`;
450
-
451
- const startTime = Date.now();
452
- const res = await this.client.scard(pkey);
453
- const duration = Date.now() - startTime;
454
- this.logSlow("SCARD", pkey, duration);
455
- return res;
287
+ return await this.client.scard(pkey);
456
288
  } catch (error) {
457
289
  Logger.error("Redis scard 错误", error);
458
290
  return 0;
@@ -467,12 +299,7 @@ export class RedisHelper {
467
299
  async smembers(key) {
468
300
  try {
469
301
  const pkey = `${this.prefix}${key}`;
470
-
471
- const startTime = Date.now();
472
- const res = await this.client.smembers(pkey);
473
- const duration = Date.now() - startTime;
474
- this.logSlow("SMEMBERS", pkey, duration);
475
- return res;
302
+ return await this.client.smembers(pkey);
476
303
  } catch (error) {
477
304
  Logger.error("Redis smembers 错误", error);
478
305
  return [];
@@ -524,12 +351,7 @@ export class RedisHelper {
524
351
  async del(key) {
525
352
  try {
526
353
  const pkey = `${this.prefix}${key}`;
527
-
528
- const startTime = Date.now();
529
- const res = await this.client.del(pkey);
530
- const duration = Date.now() - startTime;
531
- this.logSlow("DEL", pkey, duration);
532
- return res;
354
+ return await this.client.del(pkey);
533
355
  } catch (error) {
534
356
  Logger.error("Redis del 错误", error);
535
357
  return 0;
@@ -649,10 +471,7 @@ export class RedisHelper {
649
471
  });
650
472
  }
651
473
 
652
- const startTime = Date.now();
653
474
  const res = await client.info(section);
654
- const duration = Date.now() - startTime;
655
- this.logSlow("INFO", "(no-key)", duration, { section: section ?? "" });
656
475
  return res;
657
476
  } catch (error) {
658
477
  Logger.error("Redis info 错误", error);
@@ -666,11 +485,7 @@ export class RedisHelper {
666
485
  */
667
486
  async ping() {
668
487
  try {
669
- const startTime = Date.now();
670
- const res = await this.client.ping();
671
- const duration = Date.now() - startTime;
672
- this.logSlow("PING", "(no-key)", duration);
673
- return res;
488
+ return await this.client.ping();
674
489
  } catch (error) {
675
490
  Logger.error("Redis ping 错误", error);
676
491
  throw new Error("Redis ping 错误", {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.17.8",
4
- "gitHead": "ff02e6df24881973a91e4943381ba8559ed9c55d",
3
+ "version": "3.17.10",
4
+ "gitHead": "7f5250a2de8ff14fa0c838bdce4bac269c6eccf4",
5
5
  "private": false,
6
6
  "description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
7
7
  "keywords": [
package/sync/cache.js CHANGED
@@ -1,3 +1,4 @@
1
+ // 1
1
2
  export async function syncCache(ctx) {
2
3
  const tasks = [
3
4
  { name: "cacheApis", run: () => ctx.cache.cacheApis() },