@nicnocquee/dataqueue 1.39.0-beta.20260322125514 → 1.40.0-beta.20260612032253

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
@@ -593,8 +593,11 @@ var createProcessor = (backend, handlers, options = {}, onBeforeBatch, emit) =>
593
593
  );
594
594
  }
595
595
  let running = false;
596
- let intervalId = null;
597
- let currentBatchPromise = null;
596
+ let pollTimer = null;
597
+ let claimInProgress = false;
598
+ let pumpRequested = false;
599
+ let inFlight = 0;
600
+ const inFlightJobs = /* @__PURE__ */ new Set();
598
601
  setLogContext(options.verbose ?? false);
599
602
  const processJobs = async () => {
600
603
  if (!running) return 0;
@@ -636,29 +639,80 @@ var createProcessor = (backend, handlers, options = {}, onBeforeBatch, emit) =>
636
639
  return {
637
640
  /**
638
641
  * Start the job processor in the background.
639
- * - This will run periodically (every pollInterval milliseconds or 5 seconds if not provided) and process jobs as they become available.
642
+ * - Keeps up to `concurrency` jobs in flight, refilling each slot as soon as
643
+ * it frees instead of waiting for a whole batch to settle.
644
+ * - Polls every `pollInterval` milliseconds (5 seconds if not provided) for
645
+ * new work and to enqueue due cron jobs.
640
646
  * - You have to call the stop method to stop the processor.
641
647
  */
642
648
  startInBackground: () => {
643
649
  if (running) return;
644
650
  log(`Starting job processor with workerId: ${workerId}`);
645
651
  running = true;
646
- const scheduleNext = (immediate) => {
652
+ const pump = async () => {
647
653
  if (!running) return;
648
- if (immediate) {
649
- intervalId = setTimeout(loop, 0);
650
- } else {
651
- intervalId = setTimeout(loop, pollInterval);
654
+ if (claimInProgress) {
655
+ pumpRequested = true;
656
+ return;
657
+ }
658
+ if (inFlight >= concurrency) return;
659
+ claimInProgress = true;
660
+ pumpRequested = false;
661
+ let claimLimit = 0;
662
+ let claimed = 0;
663
+ try {
664
+ claimLimit = Math.min(concurrency - inFlight, batchSize);
665
+ const jobs = await backend.getNextBatch(workerId, claimLimit, jobType, groupConcurrency);
666
+ claimed = jobs.length;
667
+ for (const job of jobs) {
668
+ emit?.("job:processing", { jobId: job.id, jobType: job.jobType });
669
+ inFlight++;
670
+ const jobPromise = processJobWithHandlers(
671
+ backend,
672
+ job,
673
+ handlers,
674
+ emit
675
+ ).catch((err) => {
676
+ onError(err instanceof Error ? err : new Error(String(err)));
677
+ }).finally(() => {
678
+ inFlight--;
679
+ inFlightJobs.delete(jobPromise);
680
+ void pump();
681
+ });
682
+ inFlightJobs.add(jobPromise);
683
+ }
684
+ } catch (error) {
685
+ const err = error instanceof Error ? error : new Error(String(error));
686
+ onError(err);
687
+ emit?.("error", err);
688
+ } finally {
689
+ claimInProgress = false;
690
+ }
691
+ const moreLikely = claimed === claimLimit || pumpRequested;
692
+ if (running && moreLikely && inFlight < concurrency) {
693
+ void pump();
652
694
  }
653
695
  };
654
- const loop = async () => {
696
+ const tick = async () => {
655
697
  if (!running) return;
656
- currentBatchPromise = processJobs();
657
- const processed = await currentBatchPromise;
658
- currentBatchPromise = null;
659
- scheduleNext(processed === batchSize);
698
+ if (onBeforeBatch) {
699
+ try {
700
+ await onBeforeBatch();
701
+ } catch (hookError) {
702
+ log(`onBeforeBatch hook error: ${hookError}`);
703
+ const err = hookError instanceof Error ? hookError : new Error(String(hookError));
704
+ onError(err);
705
+ emit?.("error", err);
706
+ }
707
+ }
708
+ await pump();
709
+ if (running) {
710
+ pollTimer = setTimeout(() => {
711
+ void tick();
712
+ }, pollInterval);
713
+ }
660
714
  };
661
- loop();
715
+ void tick();
662
716
  },
663
717
  /**
664
718
  * Stop the job processor that runs in the background.
@@ -667,9 +721,9 @@ var createProcessor = (backend, handlers, options = {}, onBeforeBatch, emit) =>
667
721
  stop: () => {
668
722
  log(`Stopping job processor with workerId: ${workerId}`);
669
723
  running = false;
670
- if (intervalId) {
671
- clearTimeout(intervalId);
672
- intervalId = null;
724
+ if (pollTimer) {
725
+ clearTimeout(pollTimer);
726
+ pollTimer = null;
673
727
  }
674
728
  },
675
729
  /**
@@ -679,17 +733,15 @@ var createProcessor = (backend, handlers, options = {}, onBeforeBatch, emit) =>
679
733
  stopAndDrain: async (drainTimeoutMs = 3e4) => {
680
734
  log(`Stopping and draining job processor with workerId: ${workerId}`);
681
735
  running = false;
682
- if (intervalId) {
683
- clearTimeout(intervalId);
684
- intervalId = null;
736
+ if (pollTimer) {
737
+ clearTimeout(pollTimer);
738
+ pollTimer = null;
685
739
  }
686
- if (currentBatchPromise) {
740
+ if (inFlightJobs.size > 0) {
687
741
  await Promise.race([
688
- currentBatchPromise.catch(() => {
689
- }),
742
+ Promise.allSettled(Array.from(inFlightJobs)),
690
743
  new Promise((resolve) => setTimeout(resolve, drainTimeoutMs))
691
744
  ]);
692
- currentBatchPromise = null;
693
745
  }
694
746
  log(`Job processor ${workerId} drained`);
695
747
  },