power-queues 2.1.1 → 2.1.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.
package/dist/index.cjs CHANGED
@@ -283,9 +283,9 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
283
283
  this.idemLockTimeout = 18e4;
284
284
  this.idemDoneTimeout = 6e4;
285
285
  this.logStatus = false;
286
- this.logStatusTimeout = 3e5;
286
+ this.logStatusTimeout = 6e5;
287
287
  this.approveCount = 2e3;
288
- this.removeOnExecuted = false;
288
+ this.removeOnExecuted = true;
289
289
  }
290
290
  signal() {
291
291
  return this.abort.signal;
@@ -316,7 +316,7 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
316
316
  } catch (err) {
317
317
  }
318
318
  if (!(0, import_full_utils.isArrFilled)(tasks)) {
319
- await (0, import_full_utils.wait)(400);
319
+ await (0, import_full_utils.wait)(300);
320
320
  continue;
321
321
  }
322
322
  try {
@@ -327,7 +327,7 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
327
327
  await this.approve(queueName, tasks.map((task) => task[0]));
328
328
  } catch {
329
329
  }
330
- await (0, import_full_utils.wait)(400);
330
+ await (0, import_full_utils.wait)(300);
331
331
  }
332
332
  }
333
333
  }
@@ -345,7 +345,7 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
345
345
  const filteredTasks = filtered[key];
346
346
  const keySplit = key.split(":");
347
347
  const attempt = Number(keySplit[0]);
348
- await this.addTasks(queueName + (attempt + 1 >= this.retryCount ? ":dlq" : ""), filteredTasks.map((task) => ({ ...task[1] })), {
348
+ await this.addTasks(queueName + (attempt >= this.retryCount - 1 ? ":dlq" : ""), filteredTasks.map((task) => ({ ...task[1] })), {
349
349
  createdAt: Number(keySplit[1]),
350
350
  job: keySplit[2],
351
351
  attempt: attempt + 1
@@ -360,15 +360,15 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
360
360
  throw new Error(`Batch error. ${err2.message}`);
361
361
  }
362
362
  }
363
- async approve(queueName, ids) {
364
- if (!(0, import_full_utils.isArrFilled)(ids)) {
363
+ async approve(queueName, tasks) {
364
+ if (!(0, import_full_utils.isArrFilled)(tasks)) {
365
365
  return 0;
366
366
  }
367
367
  const approveCount = Math.max(500, Math.min(4e3, this.approveCount));
368
368
  let total = 0, i = 0;
369
- while (i < ids.length) {
370
- const room = Math.min(approveCount, ids.length - i);
371
- const part = ids.slice(i, i + room);
369
+ while (i < tasks.length) {
370
+ const room = Math.min(approveCount, tasks.length - i);
371
+ const part = tasks.slice(i, i + room).map((item) => String(item.id || ""));
372
372
  const approved = await this.runScript("Approve", [queueName], [this.group, this.removeOnExecuted ? "1" : "0", ...part], Approve);
373
373
  total += Number(approved || 0);
374
374
  i += room;
@@ -452,27 +452,27 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
452
452
  let contended = 0, promises = [];
453
453
  for (const [id, payload, createdAt, job, idemKey, attempt] of tasks) {
454
454
  if (!this.executeSync) {
455
- promises.push((async () => {
455
+ promises.push(async () => {
456
456
  const r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });
457
457
  if (r.id) {
458
- result.push(id);
458
+ result.push(r);
459
459
  } else if (r.contended) {
460
460
  contended++;
461
461
  }
462
- })());
462
+ });
463
463
  } else {
464
464
  const r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });
465
465
  if (r.id) {
466
- result.push(id);
466
+ result.push(r);
467
467
  } else if (r.contended) {
468
468
  contended++;
469
469
  }
470
470
  }
471
471
  }
472
472
  if (!this.executeSync && promises.length > 0) {
473
- await Promise.all(promises);
473
+ await Promise.all(promises.map((item) => item));
474
474
  }
475
- await this.onBatchSuccess(queueName, tasks);
475
+ await this.onBatchReady(queueName, result);
476
476
  if (!(0, import_full_utils.isArrFilled)(result) && contended > tasks.length >> 1) {
477
477
  await this.waitAbortable(15 + Math.floor(Math.random() * 35) + Math.min(250, 15 * contended + Math.floor(Math.random() * 40)));
478
478
  }
@@ -482,7 +482,7 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
482
482
  const keys = this.idempotencyKeys(queueName, String(task.idemKey));
483
483
  const allow = await this.idempotencyAllow(keys);
484
484
  if (allow === 1) {
485
- return { id: task.id };
485
+ return { contended: true };
486
486
  } else if (allow === 0) {
487
487
  let ttl = -2;
488
488
  try {
@@ -498,19 +498,13 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
498
498
  const heartbeat = this.heartbeat(keys) || (() => {
499
499
  });
500
500
  try {
501
- await this.onExecute(queueName, task);
501
+ const processed = await this.onExecute(queueName, task);
502
502
  await this.idempotencyDone(keys);
503
- await this.success(queueName, task);
504
- return { id: task.id };
503
+ return await this.success(queueName, processed);
505
504
  } catch (err) {
506
505
  try {
507
- task.attempt = task.attempt + 1;
508
- await this.error(err, queueName, task);
509
- if (task.attempt >= this.retryCount) {
510
- await this.idempotencyFree(keys);
511
- return { id: task.id };
512
- }
513
506
  await this.idempotencyFree(keys);
507
+ return await this.error(err, queueName, task);
514
508
  } catch (err2) {
515
509
  }
516
510
  } finally {
@@ -552,31 +546,31 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
552
546
  await this.incr(statusKey + "ok", this.logStatusTimeout);
553
547
  await this.incr(statusKey + "ready", this.logStatusTimeout);
554
548
  }
555
- await this.onSuccess(queueName, task);
549
+ return await this.onSuccess(queueName, task);
556
550
  }
557
551
  async error(err, queueName, task) {
558
552
  const dlqKey = queueName + ":dlq";
559
553
  const taskP = { ...task };
560
- if (task.attempt >= this.retryCount) {
561
- const statusKey = `${queueName}:${task.job}:`;
562
- await this.addTasks(dlqKey, [{ ...taskP.payload }], {
563
- createdAt: task.createdAt,
564
- job: task.job,
565
- attempt: task.attempt
566
- });
554
+ if (taskP.attempt >= this.retryCount - 1) {
555
+ const statusKey = `${queueName}:${taskP.job}:`;
567
556
  if (this.logStatus) {
568
557
  await this.incr(statusKey + "err", this.logStatusTimeout);
569
558
  await this.incr(statusKey + "ready", this.logStatusTimeout);
570
559
  }
560
+ await this.addTasks(dlqKey, [{ ...taskP.payload }], {
561
+ createdAt: taskP.createdAt,
562
+ job: taskP.job,
563
+ attempt: taskP.attempt
564
+ });
571
565
  } else {
572
- await this.onRetry(err, queueName, task);
566
+ await this.onRetry(err, queueName, taskP);
573
567
  await this.addTasks(queueName, [{ ...taskP.payload }], {
574
- createdAt: task.createdAt,
575
- job: task.job,
576
- attempt: task.attempt
568
+ createdAt: taskP.createdAt,
569
+ job: taskP.job,
570
+ attempt: (taskP.attempt || 0) + 1
577
571
  });
578
572
  }
579
- await this.onError(err, queueName, task);
573
+ return await this.onError(err, queueName, { ...taskP, attempt: (taskP.attempt || 0) + 1 });
580
574
  }
581
575
  async waitAbortable(ttl) {
582
576
  return new Promise((resolve) => {
@@ -586,7 +580,7 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
586
580
  }
587
581
  let delay;
588
582
  if (ttl > 0) {
589
- const base = Math.max(25, Math.min(ttl, 5e3));
583
+ const base = Math.max(25, Math.min(ttl, 4e3));
590
584
  const jitter = Math.floor(Math.min(base, 200) * Math.random());
591
585
  delay = base + jitter;
592
586
  } else {
@@ -836,12 +830,15 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
836
830
  return tasks;
837
831
  }
838
832
  async onExecute(queueName, task) {
833
+ return task;
839
834
  }
840
- async onBatchSuccess(queueName, tasks) {
835
+ async onBatchReady(queueName, tasks) {
841
836
  }
842
837
  async onSuccess(queueName, task) {
838
+ return task;
843
839
  }
844
840
  async onError(err, queueName, task) {
841
+ return task;
845
842
  }
846
843
  async onBatchError(err, queueName, tasks) {
847
844
  }
package/dist/index.d.cts CHANGED
@@ -81,12 +81,12 @@ declare class PowerQueues extends PowerRedis {
81
81
  private buildBatches;
82
82
  private keysLength;
83
83
  private payloadBatch;
84
- beforeExecute(queueName: string, tasks: Array<[string, any[], number, string, string, number]>): Promise<[string, any[], number, string, string, number][]>;
85
- onExecute(queueName: string, task: Task): Promise<void>;
86
- onBatchSuccess(queueName: string, tasks: Array<[string, any[], number, string, string, number]>): Promise<void>;
87
- onSuccess(queueName: string, task: Task): Promise<void>;
88
- onError(err: any, queueName: string, task: Task): Promise<void>;
89
- onBatchError(err: any, queueName: string, tasks: Array<[string, any[], number, string, string, number]>): Promise<void>;
84
+ beforeExecute(queueName: string, tasks: Array<[string, any, number, string, string, number]>): Promise<[string, any, number, string, string, number][]>;
85
+ onExecute(queueName: string, task: Task): Promise<Task>;
86
+ onBatchReady(queueName: string, tasks: Array<Task>): Promise<void>;
87
+ onSuccess(queueName: string, task: Task): Promise<Task>;
88
+ onError(err: any, queueName: string, task: Task): Promise<Task>;
89
+ onBatchError(err: any, queueName: string, tasks: Array<[string, any, number, string, string, number]>): Promise<void>;
90
90
  onRetry(err: any, queueName: string, task: Task): Promise<void>;
91
91
  }
92
92
 
package/dist/index.d.ts CHANGED
@@ -81,12 +81,12 @@ declare class PowerQueues extends PowerRedis {
81
81
  private buildBatches;
82
82
  private keysLength;
83
83
  private payloadBatch;
84
- beforeExecute(queueName: string, tasks: Array<[string, any[], number, string, string, number]>): Promise<[string, any[], number, string, string, number][]>;
85
- onExecute(queueName: string, task: Task): Promise<void>;
86
- onBatchSuccess(queueName: string, tasks: Array<[string, any[], number, string, string, number]>): Promise<void>;
87
- onSuccess(queueName: string, task: Task): Promise<void>;
88
- onError(err: any, queueName: string, task: Task): Promise<void>;
89
- onBatchError(err: any, queueName: string, tasks: Array<[string, any[], number, string, string, number]>): Promise<void>;
84
+ beforeExecute(queueName: string, tasks: Array<[string, any, number, string, string, number]>): Promise<[string, any, number, string, string, number][]>;
85
+ onExecute(queueName: string, task: Task): Promise<Task>;
86
+ onBatchReady(queueName: string, tasks: Array<Task>): Promise<void>;
87
+ onSuccess(queueName: string, task: Task): Promise<Task>;
88
+ onError(err: any, queueName: string, task: Task): Promise<Task>;
89
+ onBatchError(err: any, queueName: string, tasks: Array<[string, any, number, string, string, number]>): Promise<void>;
90
90
  onRetry(err: any, queueName: string, task: Task): Promise<void>;
91
91
  }
92
92
 
package/dist/index.js CHANGED
@@ -266,9 +266,9 @@ var PowerQueues = class extends PowerRedis {
266
266
  this.idemLockTimeout = 18e4;
267
267
  this.idemDoneTimeout = 6e4;
268
268
  this.logStatus = false;
269
- this.logStatusTimeout = 3e5;
269
+ this.logStatusTimeout = 6e5;
270
270
  this.approveCount = 2e3;
271
- this.removeOnExecuted = false;
271
+ this.removeOnExecuted = true;
272
272
  }
273
273
  signal() {
274
274
  return this.abort.signal;
@@ -299,7 +299,7 @@ var PowerQueues = class extends PowerRedis {
299
299
  } catch (err) {
300
300
  }
301
301
  if (!isArrFilled(tasks)) {
302
- await wait(400);
302
+ await wait(300);
303
303
  continue;
304
304
  }
305
305
  try {
@@ -310,7 +310,7 @@ var PowerQueues = class extends PowerRedis {
310
310
  await this.approve(queueName, tasks.map((task) => task[0]));
311
311
  } catch {
312
312
  }
313
- await wait(400);
313
+ await wait(300);
314
314
  }
315
315
  }
316
316
  }
@@ -328,7 +328,7 @@ var PowerQueues = class extends PowerRedis {
328
328
  const filteredTasks = filtered[key];
329
329
  const keySplit = key.split(":");
330
330
  const attempt = Number(keySplit[0]);
331
- await this.addTasks(queueName + (attempt + 1 >= this.retryCount ? ":dlq" : ""), filteredTasks.map((task) => ({ ...task[1] })), {
331
+ await this.addTasks(queueName + (attempt >= this.retryCount - 1 ? ":dlq" : ""), filteredTasks.map((task) => ({ ...task[1] })), {
332
332
  createdAt: Number(keySplit[1]),
333
333
  job: keySplit[2],
334
334
  attempt: attempt + 1
@@ -343,15 +343,15 @@ var PowerQueues = class extends PowerRedis {
343
343
  throw new Error(`Batch error. ${err2.message}`);
344
344
  }
345
345
  }
346
- async approve(queueName, ids) {
347
- if (!isArrFilled(ids)) {
346
+ async approve(queueName, tasks) {
347
+ if (!isArrFilled(tasks)) {
348
348
  return 0;
349
349
  }
350
350
  const approveCount = Math.max(500, Math.min(4e3, this.approveCount));
351
351
  let total = 0, i = 0;
352
- while (i < ids.length) {
353
- const room = Math.min(approveCount, ids.length - i);
354
- const part = ids.slice(i, i + room);
352
+ while (i < tasks.length) {
353
+ const room = Math.min(approveCount, tasks.length - i);
354
+ const part = tasks.slice(i, i + room).map((item) => String(item.id || ""));
355
355
  const approved = await this.runScript("Approve", [queueName], [this.group, this.removeOnExecuted ? "1" : "0", ...part], Approve);
356
356
  total += Number(approved || 0);
357
357
  i += room;
@@ -435,27 +435,27 @@ var PowerQueues = class extends PowerRedis {
435
435
  let contended = 0, promises = [];
436
436
  for (const [id, payload, createdAt, job, idemKey, attempt] of tasks) {
437
437
  if (!this.executeSync) {
438
- promises.push((async () => {
438
+ promises.push(async () => {
439
439
  const r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });
440
440
  if (r.id) {
441
- result.push(id);
441
+ result.push(r);
442
442
  } else if (r.contended) {
443
443
  contended++;
444
444
  }
445
- })());
445
+ });
446
446
  } else {
447
447
  const r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });
448
448
  if (r.id) {
449
- result.push(id);
449
+ result.push(r);
450
450
  } else if (r.contended) {
451
451
  contended++;
452
452
  }
453
453
  }
454
454
  }
455
455
  if (!this.executeSync && promises.length > 0) {
456
- await Promise.all(promises);
456
+ await Promise.all(promises.map((item) => item));
457
457
  }
458
- await this.onBatchSuccess(queueName, tasks);
458
+ await this.onBatchReady(queueName, result);
459
459
  if (!isArrFilled(result) && contended > tasks.length >> 1) {
460
460
  await this.waitAbortable(15 + Math.floor(Math.random() * 35) + Math.min(250, 15 * contended + Math.floor(Math.random() * 40)));
461
461
  }
@@ -465,7 +465,7 @@ var PowerQueues = class extends PowerRedis {
465
465
  const keys = this.idempotencyKeys(queueName, String(task.idemKey));
466
466
  const allow = await this.idempotencyAllow(keys);
467
467
  if (allow === 1) {
468
- return { id: task.id };
468
+ return { contended: true };
469
469
  } else if (allow === 0) {
470
470
  let ttl = -2;
471
471
  try {
@@ -481,19 +481,13 @@ var PowerQueues = class extends PowerRedis {
481
481
  const heartbeat = this.heartbeat(keys) || (() => {
482
482
  });
483
483
  try {
484
- await this.onExecute(queueName, task);
484
+ const processed = await this.onExecute(queueName, task);
485
485
  await this.idempotencyDone(keys);
486
- await this.success(queueName, task);
487
- return { id: task.id };
486
+ return await this.success(queueName, processed);
488
487
  } catch (err) {
489
488
  try {
490
- task.attempt = task.attempt + 1;
491
- await this.error(err, queueName, task);
492
- if (task.attempt >= this.retryCount) {
493
- await this.idempotencyFree(keys);
494
- return { id: task.id };
495
- }
496
489
  await this.idempotencyFree(keys);
490
+ return await this.error(err, queueName, task);
497
491
  } catch (err2) {
498
492
  }
499
493
  } finally {
@@ -535,31 +529,31 @@ var PowerQueues = class extends PowerRedis {
535
529
  await this.incr(statusKey + "ok", this.logStatusTimeout);
536
530
  await this.incr(statusKey + "ready", this.logStatusTimeout);
537
531
  }
538
- await this.onSuccess(queueName, task);
532
+ return await this.onSuccess(queueName, task);
539
533
  }
540
534
  async error(err, queueName, task) {
541
535
  const dlqKey = queueName + ":dlq";
542
536
  const taskP = { ...task };
543
- if (task.attempt >= this.retryCount) {
544
- const statusKey = `${queueName}:${task.job}:`;
545
- await this.addTasks(dlqKey, [{ ...taskP.payload }], {
546
- createdAt: task.createdAt,
547
- job: task.job,
548
- attempt: task.attempt
549
- });
537
+ if (taskP.attempt >= this.retryCount - 1) {
538
+ const statusKey = `${queueName}:${taskP.job}:`;
550
539
  if (this.logStatus) {
551
540
  await this.incr(statusKey + "err", this.logStatusTimeout);
552
541
  await this.incr(statusKey + "ready", this.logStatusTimeout);
553
542
  }
543
+ await this.addTasks(dlqKey, [{ ...taskP.payload }], {
544
+ createdAt: taskP.createdAt,
545
+ job: taskP.job,
546
+ attempt: taskP.attempt
547
+ });
554
548
  } else {
555
- await this.onRetry(err, queueName, task);
549
+ await this.onRetry(err, queueName, taskP);
556
550
  await this.addTasks(queueName, [{ ...taskP.payload }], {
557
- createdAt: task.createdAt,
558
- job: task.job,
559
- attempt: task.attempt
551
+ createdAt: taskP.createdAt,
552
+ job: taskP.job,
553
+ attempt: (taskP.attempt || 0) + 1
560
554
  });
561
555
  }
562
- await this.onError(err, queueName, task);
556
+ return await this.onError(err, queueName, { ...taskP, attempt: (taskP.attempt || 0) + 1 });
563
557
  }
564
558
  async waitAbortable(ttl) {
565
559
  return new Promise((resolve) => {
@@ -569,7 +563,7 @@ var PowerQueues = class extends PowerRedis {
569
563
  }
570
564
  let delay;
571
565
  if (ttl > 0) {
572
- const base = Math.max(25, Math.min(ttl, 5e3));
566
+ const base = Math.max(25, Math.min(ttl, 4e3));
573
567
  const jitter = Math.floor(Math.min(base, 200) * Math.random());
574
568
  delay = base + jitter;
575
569
  } else {
@@ -819,12 +813,15 @@ var PowerQueues = class extends PowerRedis {
819
813
  return tasks;
820
814
  }
821
815
  async onExecute(queueName, task) {
816
+ return task;
822
817
  }
823
- async onBatchSuccess(queueName, tasks) {
818
+ async onBatchReady(queueName, tasks) {
824
819
  }
825
820
  async onSuccess(queueName, task) {
821
+ return task;
826
822
  }
827
823
  async onError(err, queueName, task) {
824
+ return task;
828
825
  }
829
826
  async onBatchError(err, queueName, tasks) {
830
827
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "power-queues",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "High-performance Redis Streams queue for Node.js with Lua-powered bulk XADD, idempotent workers, heartbeat locks, stuck-task recovery, retries, DLQ, and distributed processing.",
5
5
  "author": "ihor-bielchenko",
6
6
  "license": "MIT",