bopodev-api 0.1.30 → 0.1.31

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.
@@ -3,6 +3,7 @@ import type { RealtimeHub } from "../realtime/hub";
3
3
  import { runHeartbeatSweep } from "../services/heartbeat-service";
4
4
  import { runHeartbeatQueueSweep } from "../services/heartbeat-queue-service";
5
5
  import { runIssueCommentDispatchSweep } from "../services/comment-recipient-dispatch-service";
6
+ import { runLoopSweep } from "../services/work-loop-service";
6
7
 
7
8
  export type HeartbeatSchedulerHandle = {
8
9
  stop: () => Promise<void>;
@@ -12,12 +13,16 @@ export function createHeartbeatScheduler(db: BopoDb, companyId: string, realtime
12
13
  const heartbeatIntervalMs = Number(process.env.BOPO_HEARTBEAT_SWEEP_MS ?? 60_000);
13
14
  const queueIntervalMs = Number(process.env.BOPO_HEARTBEAT_QUEUE_SWEEP_MS ?? 2_000);
14
15
  const commentDispatchIntervalMs = Number(process.env.BOPO_COMMENT_DISPATCH_SWEEP_MS ?? 3_000);
16
+ const loopSweepIntervalMs = Number(process.env.BOPO_LOOP_SWEEP_MS ?? 60_000);
17
+ const loopSweepEnabled = (process.env.BOPO_LOOP_SWEEP_ENABLED ?? "1").trim() !== "0";
15
18
  let heartbeatRunning = false;
16
19
  let queueRunning = false;
17
20
  let commentDispatchRunning = false;
21
+ let loopSweepRunning = false;
18
22
  let heartbeatPromise: Promise<unknown> | null = null;
19
23
  let queuePromise: Promise<unknown> | null = null;
20
24
  let commentDispatchPromise: Promise<unknown> | null = null;
25
+ let loopSweepPromise: Promise<unknown> | null = null;
21
26
  const heartbeatTimer = setInterval(() => {
22
27
  if (heartbeatRunning) {
23
28
  return;
@@ -63,12 +68,32 @@ export function createHeartbeatScheduler(db: BopoDb, companyId: string, realtime
63
68
  commentDispatchPromise = null;
64
69
  });
65
70
  }, commentDispatchIntervalMs);
71
+ const loopSweepTimer = loopSweepEnabled
72
+ ? setInterval(() => {
73
+ if (loopSweepRunning) {
74
+ return;
75
+ }
76
+ loopSweepRunning = true;
77
+ loopSweepPromise = runLoopSweep(db, companyId, { realtimeHub })
78
+ .catch((error) => {
79
+ // eslint-disable-next-line no-console
80
+ console.error("[scheduler] work loop sweep failed", error);
81
+ })
82
+ .finally(() => {
83
+ loopSweepRunning = false;
84
+ loopSweepPromise = null;
85
+ });
86
+ }, loopSweepIntervalMs)
87
+ : null;
66
88
  const stop = async () => {
67
89
  clearInterval(heartbeatTimer);
68
90
  clearInterval(queueTimer);
69
91
  clearInterval(commentDispatchTimer);
92
+ if (loopSweepTimer) {
93
+ clearInterval(loopSweepTimer);
94
+ }
70
95
  await Promise.allSettled(
71
- [heartbeatPromise, queuePromise, commentDispatchPromise].filter(
96
+ [heartbeatPromise, queuePromise, commentDispatchPromise, loopSweepPromise].filter(
72
97
  (promise): promise is Promise<unknown> => promise !== null
73
98
  )
74
99
  );