@jayfong/x-server 1.35.2 → 1.35.3

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.
@@ -6,6 +6,8 @@ exports.__esModule = true;
6
6
  exports.defineSliceTask = defineSliceTask;
7
7
  exports.defineTask = defineTask;
8
8
 
9
+ var _assert = _interopRequireDefault(require("assert"));
10
+
9
11
  var _bull = _interopRequireDefault(require("bull"));
10
12
 
11
13
  var _date = require("vtils/date");
@@ -37,25 +39,59 @@ function defineSliceTask(options) {
37
39
  name: options.name,
38
40
  concurrency: 1,
39
41
  handle: async data => {
40
- const res = await _x.x.redis.multi([['lrange', data.redisKey, '0', '-1'], ['del', data.redisKey]]).exec();
41
- const list = res[0][1].map(item => JSON.parse(item));
42
- return options.handle(list, data.key);
42
+ const res = data.count ? await _x.x.redis.multi([['lrange', data.redisKey, `-${data.count}`, '-1'], ['ltrim', data.redisKey, '0', `-${data.count + 1}`]]).exec() : await _x.x.redis.multi([['lrange', data.redisKey, '0', '-1'], ['del', data.redisKey]]).exec();
43
+ const list = res[0][1].reverse().map(item => JSON.parse(item));
44
+
45
+ if (list.length) {
46
+ return options.handle(list, data.key);
47
+ }
43
48
  }
44
49
  });
45
50
  const redisKeyPrefix = `${_x.x.appId}_batch_task_${options.name}`;
46
51
  const res = {
47
52
  add: async (data, addOptions) => {
48
53
  const key = (addOptions == null ? void 0 : addOptions.key) || '';
54
+ const duration = (addOptions == null ? void 0 : addOptions.duration) != null ? (0, _date.ms)(addOptions.duration) : typeof options.duration === 'function' ? (0, _date.ms)(options.duration(key)) : options.duration && (0, _date.ms)(options.duration);
55
+ const threshold = (addOptions == null ? void 0 : addOptions.threshold) || typeof options.threshold && (typeof options.threshold === 'function' ? options.threshold(key) : options.threshold);
56
+ (0, _assert.default)(duration != null || threshold != null, '参数 threshold 和 duration 必须至少设置 1 个');
49
57
  const redisKey = !key ? redisKeyPrefix : `${redisKeyPrefix}_${key}`;
50
58
  const res = await _x.x.redis.multi([['llen', redisKey], ['lpush', redisKey, JSON.stringify(data)]]).exec();
59
+ const count = parseInt(res[0][1], 10) + 1; // 时段与阈值并存
51
60
 
52
- if (parseInt(res[0][1], 10) === 0) {
53
- await task.add({
54
- key: key,
55
- redisKey: redisKey
56
- }, {
57
- delay: (addOptions == null ? void 0 : addOptions.duration) != null ? (0, _date.ms)(addOptions.duration) : typeof options.duration === 'function' ? (0, _date.ms)(options.duration(key)) : (0, _date.ms)(options.duration)
58
- });
61
+ if (duration != null && threshold != null) {
62
+ if (count === threshold) {
63
+ await task.add({
64
+ key: key,
65
+ redisKey: redisKey,
66
+ count: threshold
67
+ });
68
+ } else if (count === 1) {
69
+ await task.add({
70
+ key: key,
71
+ redisKey: redisKey
72
+ }, {
73
+ delay: duration
74
+ });
75
+ }
76
+ } // 仅时段
77
+ else if (duration != null) {
78
+ if (count === 1) {
79
+ await task.add({
80
+ key: key,
81
+ redisKey: redisKey
82
+ }, {
83
+ delay: duration
84
+ });
85
+ }
86
+ } // 仅阈值
87
+ else if (threshold != null) {
88
+ if (count === threshold) {
89
+ await task.add({
90
+ key: key,
91
+ redisKey: redisKey,
92
+ count: threshold
93
+ });
94
+ }
59
95
  }
60
96
  }
61
97
  };
@@ -1,3 +1,4 @@
1
+ import assert from 'assert';
1
2
  import Queue from 'bull';
2
3
  import { ms } from 'vtils/date';
3
4
  import { x } from "../x";
@@ -25,25 +26,59 @@ export function defineSliceTask(options) {
25
26
  name: options.name,
26
27
  concurrency: 1,
27
28
  handle: async data => {
28
- const res = await x.redis.multi([['lrange', data.redisKey, '0', '-1'], ['del', data.redisKey]]).exec();
29
- const list = res[0][1].map(item => JSON.parse(item));
30
- return options.handle(list, data.key);
29
+ const res = data.count ? await x.redis.multi([['lrange', data.redisKey, `-${data.count}`, '-1'], ['ltrim', data.redisKey, '0', `-${data.count + 1}`]]).exec() : await x.redis.multi([['lrange', data.redisKey, '0', '-1'], ['del', data.redisKey]]).exec();
30
+ const list = res[0][1].reverse().map(item => JSON.parse(item));
31
+
32
+ if (list.length) {
33
+ return options.handle(list, data.key);
34
+ }
31
35
  }
32
36
  });
33
37
  const redisKeyPrefix = `${x.appId}_batch_task_${options.name}`;
34
38
  const res = {
35
39
  add: async (data, addOptions) => {
36
40
  const key = (addOptions == null ? void 0 : addOptions.key) || '';
41
+ const duration = (addOptions == null ? void 0 : addOptions.duration) != null ? ms(addOptions.duration) : typeof options.duration === 'function' ? ms(options.duration(key)) : options.duration && ms(options.duration);
42
+ const threshold = (addOptions == null ? void 0 : addOptions.threshold) || typeof options.threshold && (typeof options.threshold === 'function' ? options.threshold(key) : options.threshold);
43
+ assert(duration != null || threshold != null, '参数 threshold 和 duration 必须至少设置 1 个');
37
44
  const redisKey = !key ? redisKeyPrefix : `${redisKeyPrefix}_${key}`;
38
45
  const res = await x.redis.multi([['llen', redisKey], ['lpush', redisKey, JSON.stringify(data)]]).exec();
46
+ const count = parseInt(res[0][1], 10) + 1; // 时段与阈值并存
39
47
 
40
- if (parseInt(res[0][1], 10) === 0) {
41
- await task.add({
42
- key: key,
43
- redisKey: redisKey
44
- }, {
45
- delay: (addOptions == null ? void 0 : addOptions.duration) != null ? ms(addOptions.duration) : typeof options.duration === 'function' ? ms(options.duration(key)) : ms(options.duration)
46
- });
48
+ if (duration != null && threshold != null) {
49
+ if (count === threshold) {
50
+ await task.add({
51
+ key: key,
52
+ redisKey: redisKey,
53
+ count: threshold
54
+ });
55
+ } else if (count === 1) {
56
+ await task.add({
57
+ key: key,
58
+ redisKey: redisKey
59
+ }, {
60
+ delay: duration
61
+ });
62
+ }
63
+ } // 仅时段
64
+ else if (duration != null) {
65
+ if (count === 1) {
66
+ await task.add({
67
+ key: key,
68
+ redisKey: redisKey
69
+ }, {
70
+ delay: duration
71
+ });
72
+ }
73
+ } // 仅阈值
74
+ else if (threshold != null) {
75
+ if (count === threshold) {
76
+ await task.add({
77
+ key: key,
78
+ redisKey: redisKey,
79
+ count: threshold
80
+ });
81
+ }
47
82
  }
48
83
  }
49
84
  };
@@ -157,7 +157,7 @@ export declare namespace XTask {
157
157
  }
158
158
  interface Task<T> extends Queue<T> {
159
159
  }
160
- interface SliceTaskOptions<T, K> {
160
+ type SliceTaskOptions<T, K> = {
161
161
  /**
162
162
  * 任务名称
163
163
  */
@@ -165,21 +165,27 @@ export declare namespace XTask {
165
165
  /**
166
166
  * 持续时长
167
167
  */
168
- duration: MsValue | ((key: K) => MsValue);
168
+ duration?: MsValue | ((key: K) => MsValue);
169
+ /**
170
+ * 阈值数量
171
+ */
172
+ threshold?: number | ((key: K) => number);
169
173
  /**
170
174
  * 处理器
171
175
  */
172
176
  handle: (data: T[], key: K) => any;
173
- }
177
+ };
174
178
  interface SliceTaskNoKey<T> {
175
179
  add: (data: T, options?: {
176
180
  duration?: MsValue;
181
+ threshold?: number;
177
182
  }) => Promise<void>;
178
183
  }
179
184
  interface SliceTask<T, K> {
180
185
  add: (data: T, options: {
181
186
  key: K;
182
187
  duration?: MsValue;
188
+ threshold?: number;
183
189
  }) => Promise<void>;
184
190
  }
185
191
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayfong/x-server",
3
- "version": "1.35.2",
3
+ "version": "1.35.3",
4
4
  "license": "ISC",
5
5
  "sideEffects": false,
6
6
  "main": "lib/_cjs/index.js",
@@ -71,7 +71,7 @@
71
71
  "ts-morph": "^12.2.0",
72
72
  "utf-8-validate": "^5.0.9",
73
73
  "vscode-generate-index-standalone": "^1.6.0",
74
- "vtils": "^4.60.0",
74
+ "vtils": "^4.67.0",
75
75
  "yargs": "^17.4.1"
76
76
  },
77
77
  "devDependencies": {