@agentteams/runner 0.0.93 → 0.0.95

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/poller.js CHANGED
@@ -18,8 +18,8 @@ export const startPolling = async (config, createHandler, dependencies = {}) =>
18
18
  const autoUpdate = dependencies.maybeAutoUpdate ?? maybeAutoUpdate;
19
19
  const performRestart = dependencies.executeRestartRequest ?? executeRestartRequest;
20
20
  const now = dependencies.now ?? Date.now;
21
- const registerInterval = dependencies.setInterval ?? global.setInterval;
22
- const unregisterInterval = dependencies.clearInterval ?? global.clearInterval;
21
+ const registerTimeout = dependencies.setTimeout ?? global.setTimeout;
22
+ const unregisterTimeout = dependencies.clearTimeout ?? global.clearTimeout;
23
23
  const registerSignal = dependencies.processOn ?? ((event, listener) => process.on(event, listener));
24
24
  const exitProcess = dependencies.processExit ?? ((code) => process.exit(code));
25
25
  const keepAlive = dependencies.keepAlive ??
@@ -149,9 +149,11 @@ export const startPolling = async (config, createHandler, dependencies = {}) =>
149
149
  };
150
150
  const pollOnce = async () => {
151
151
  if (isPolling) {
152
- return;
152
+ return 'SKIPPED';
153
153
  }
154
154
  isPolling = true;
155
+ // 이번 cycle에 처리할 일이 있었는지. 순수 idle만 false로 남는다.
156
+ let hadWork = false;
155
157
  try {
156
158
  maybeRunCleanup();
157
159
  maybeRunConventionSync();
@@ -159,6 +161,9 @@ export const startPolling = async (config, createHandler, dependencies = {}) =>
159
161
  // snapshot 1회 조회로 가져온다. 실패 시 아래 catch에서 polling cycle 전체가 실패
160
162
  // 처리되어 명확한 로그를 남긴다(조용히 pending 확인만 생략하지 않는다).
161
163
  const pollState = await client.fetchPollState();
164
+ hadWork =
165
+ pollState.data.orphanedCancelRequestedTriggerIds.length > 0 ||
166
+ pollState.data.pendingWorktreeRemovals.length > 0;
162
167
  // 후속 mutation은 기존과 동일하게 개별 처리하며, 처리 순서도 보존한다.
163
168
  await autoCancelOrphanedTriggers(pollState.data.orphanedCancelRequestedTriggerIds);
164
169
  await processWorktreeRemovals(pollState.data.pendingWorktreeRemovals);
@@ -174,10 +179,11 @@ export const startPolling = async (config, createHandler, dependencies = {}) =>
174
179
  logger.warn('Failed to ack restart request — will retry on next poll', {
175
180
  error: error instanceof Error ? error.message : String(error),
176
181
  });
177
- return;
182
+ // ack 재시도를 base 간격으로 빠르게 잇기 위해 활동으로 취급한다.
183
+ return 'ACTIVE';
178
184
  }
179
185
  performRestart({ processExit: exitProcess });
180
- return;
186
+ return 'ACTIVE';
181
187
  }
182
188
  if (!trigger) {
183
189
  // idle 상태에서 자동 업데이트 시도
@@ -191,16 +197,16 @@ export const startPolling = async (config, createHandler, dependencies = {}) =>
191
197
  error: error instanceof Error ? error.message : String(error),
192
198
  });
193
199
  }
194
- return;
200
+ return hadWork ? 'ACTIVE' : 'IDLE';
195
201
  }
196
202
  const claim = await client.claimTrigger(trigger.id);
197
203
  if (claim.conflict) {
198
204
  logger.info('Trigger already claimed by another daemon', { triggerId: trigger.id });
199
- return;
205
+ return 'ACTIVE';
200
206
  }
201
207
  if (!claim.ok) {
202
208
  logger.warn('Claim was rejected', { triggerId: trigger.id });
203
- return;
209
+ return 'ACTIVE';
204
210
  }
205
211
  void onTrigger(trigger).catch((error) => {
206
212
  logger.error('Trigger handler execution failed', {
@@ -208,31 +214,65 @@ export const startPolling = async (config, createHandler, dependencies = {}) =>
208
214
  error: error instanceof Error ? error.message : String(error),
209
215
  });
210
216
  });
217
+ return 'ACTIVE';
211
218
  }
212
219
  catch (error) {
213
220
  logger.error('Polling cycle failed', {
214
221
  error: error instanceof Error ? error.message : String(error),
215
222
  });
223
+ return hadWork ? 'ACTIVE' : 'IDLE';
216
224
  }
217
225
  finally {
218
226
  isPolling = false;
219
227
  }
220
228
  };
221
- const interval = registerInterval(() => {
222
- void pollOnce();
223
- }, config.pollingIntervalMs);
229
+ // idle 적응형 백오프: 연속 idle cycle마다 다음 폴 간격을 선형 증가시키고
230
+ // (base × (1 + idleStreak × 0.5), 상한 clamp), 활동이 감지되면 즉시 base로 리셋한다.
231
+ let stopped = false;
232
+ let idleStreak = 0;
233
+ let pendingPollTimer = null;
234
+ const computeNextPollDelay = (outcome) => {
235
+ if (outcome === 'ACTIVE') {
236
+ idleStreak = 0;
237
+ return config.pollingIntervalMs;
238
+ }
239
+ idleStreak += 1;
240
+ return Math.min(config.pollingIntervalMs * (1 + idleStreak * 0.5), config.maxPollingIntervalMs);
241
+ };
242
+ const runPollCycle = async () => {
243
+ if (stopped) {
244
+ return;
245
+ }
246
+ const outcome = await pollOnce();
247
+ if (outcome === 'SKIPPED') {
248
+ // 진행 중인 cycle이 완료 시점에 다음 폴을 예약하므로 여기서 이중 예약하지 않는다.
249
+ return;
250
+ }
251
+ if (stopped) {
252
+ return;
253
+ }
254
+ pendingPollTimer = registerTimeout(() => {
255
+ void runPollCycle();
256
+ }, computeNextPollDelay(outcome));
257
+ };
224
258
  // daemon 시작과 함께 절전 방지를 한 번 acquire한다. polling cycle마다 반복하지 않는다.
225
259
  const releasePowerSaveBlocker = powerSaveBlocker.acquire('daemon-polling');
226
260
  logger.info('Daemon polling started', {
227
261
  apiUrl: config.apiUrl,
228
262
  pollingIntervalMs: config.pollingIntervalMs,
263
+ maxPollingIntervalMs: config.maxPollingIntervalMs,
229
264
  timeoutMs: config.timeoutMs,
230
265
  runnerCmd: config.runnerCmd,
231
266
  });
232
- await pollOnce();
267
+ // 부트스트랩: 즉시 1회 폴 후 자기예약 루프가 다음 폴을 이어간다.
268
+ await runPollCycle();
233
269
  const shutdown = () => {
270
+ stopped = true;
271
+ if (pendingPollTimer !== null) {
272
+ unregisterTimeout(pendingPollTimer);
273
+ pendingPollTimer = null;
274
+ }
234
275
  releasePowerSaveBlocker();
235
- unregisterInterval(interval);
236
276
  logger.info('Daemon stopped');
237
277
  exitProcess(0);
238
278
  };
@@ -1 +1 @@
1
- {"version":3,"file":"poller.js","sourceRoot":"","sources":["../src/poller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAyB,MAAM,+BAA+B,CAAC;AAM9F,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAChD,MAAM,2BAA2B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AA8BvD,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,MAAqB,EACrB,aAAoC,EACpC,eAAoC,EAAE,EACvB,EAAE;IACjB,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC7G,MAAM,aAAa,GAAG,YAAY,CAAC,UAAU,IAAI,UAAU,CAAC;IAC5D,MAAM,cAAc,GAAG,YAAY,CAAC,iBAAiB,IAAI,iBAAiB,CAAC;IAC3E,MAAM,gBAAgB,GAAG,YAAY,CAAC,cAAc,IAAI,cAAc,CAAC;IACvE,MAAM,UAAU,GAAG,YAAY,CAAC,eAAe,IAAI,eAAe,CAAC;IACnE,MAAM,cAAc,GAAG,YAAY,CAAC,qBAAqB,IAAI,qBAAqB,CAAC;IACnF,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACzC,MAAM,gBAAgB,GAAG,YAAY,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;IACxE,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC;IAC9E,MAAM,cAAc,GAAG,YAAY,CAAC,SAAS,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpG,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/E,MAAM,SAAS,GACb,YAAY,CAAC,SAAS;QACtB,CAAC,GAAG,EAAE,CACJ,IAAI,OAAO,CAAO,GAAG,EAAE;YACrB,4CAA4C;QAC9C,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,sBAAsB,GAAG,YAAY,CAAC,aAAa,IAAI,aAAa,CAAC;IAC3E,MAAM,eAAe,GAAG,YAAY,CAAC,YAAY,IAAI,YAAY,CAAC;IAClE,oEAAoE;IACpE,kDAAkD;IAClD,MAAM,gBAAgB,GACpB,YAAY,CAAC,gBAAgB,IAAI,sBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACrG,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,MAAM,cAAc,GAAG,IAAI,GAAG,CAAS,sBAAsB,EAAE,CAAC,CAAC;IACjE,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvD,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAQ,EAAE;QACtD,IAAI,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;gBACzC,QAAQ;gBACR,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAEtD,MAAM,eAAe,GAAG,GAAG,EAAE;QAC3B,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;QAC1B,IAAI,WAAW,GAAG,aAAa,GAAG,mBAAmB,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QACD,aAAa,GAAG,WAAW,CAAC;QAE5B,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;YACtC,KAAK,aAAa,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC3C,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;oBACtC,QAAQ;oBACR,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,sBAAsB,GAAG,GAAG,EAAE;QAClC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;QAC1B,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACzD,IAAI,WAAW,GAAG,QAAQ,GAAG,2BAA2B,EAAE,CAAC;gBACzD,SAAS;YACX,CAAC;YACD,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAChD,KAAK,cAAc,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC5C,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE;oBAC9C,QAAQ;oBACR,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,qDAAqD;IACrD,MAAM,0BAA0B,GAAG,KAAK,EAAE,UAAoB,EAAE,EAAE;QAChE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,WAAW,EAAE,qDAAqD,CAAC,CAAC;gBAChH,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;YAChE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE;oBACpD,SAAS;oBACT,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,wDAAwD;IACxD,MAAM,uBAAuB,GAAG,KAAK,EAAE,QAAyB,EAAE,EAAE;QAClE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,IAAI,eAAe,GAAG,KAAK,CAAC;gBAC5B,MAAM,mBAAmB,GAAG,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,EAAE,CAAC;gBAC7D,IAAI,eAAe,GAAG,KAAK,CAAC;gBAC5B,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;oBACtC,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;oBACxE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;wBAC9B,SAAS;oBACX,CAAC;oBAED,eAAe,GAAG,IAAI,CAAC;oBACvB,IAAI,CAAC;wBACH,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;wBAC9D,eAAe,GAAG,IAAI,CAAC;wBACvB,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;wBACrF,MAAM;oBACR,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,aAAa,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBAC7E,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE;4BACnD,SAAS,EAAE,OAAO,CAAC,EAAE;4BACrB,QAAQ;4BACR,YAAY;4BACZ,KAAK,EAAE,aAAa;yBACrB,CAAC,CAAC;wBACH,MAAM,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;wBACvE,MAAM;oBACR,CAAC;gBACH,CAAC;gBAED,IAAI,eAAe,EAAE,CAAC;oBACpB,MAAM,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;gBAC3D,CAAC;qBAAM,IAAI,CAAC,eAAe,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,8CAA8C,EAAE;wBAC1D,SAAS,EAAE,OAAO,CAAC,EAAE;wBACrB,UAAU,EAAE,mBAAmB;qBAChC,CAAC,CAAC;oBACH,MAAM,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE;oBACnD,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,SAAS,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC;YACH,eAAe,EAAE,CAAC;YAClB,sBAAsB,EAAE,CAAC;YAEzB,+DAA+D;YAC/D,6DAA6D;YAC7D,8CAA8C;YAC9C,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAC;YAEhD,8CAA8C;YAC9C,MAAM,0BAA0B,CAAC,SAAS,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YACnF,MAAM,uBAAuB,CAAC,SAAS,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YAEtE,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC;YAE9C,4CAA4C;YAC5C,kDAAkD;YAClD,4BAA4B;YAC5B,IAAI,SAAS,CAAC,IAAI,EAAE,gBAAgB,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC;gBACnC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CAAC,yDAAyD,EAAE;wBACrE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC9D,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBAED,cAAc,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,uBAAuB;gBACvB,IAAI,CAAC;oBACH,MAAM,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE;wBAC/B,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC;qBACrE,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;wBACvC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC9D,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACpD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC,2CAA2C,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpF,OAAO;YACT,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7D,OAAO;YACT,CAAC;YAED,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACtC,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE;oBAC/C,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE;gBACnC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,EAAE;QACrC,KAAK,QAAQ,EAAE,CAAC;IAClB,CAAC,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAE7B,gEAAgE;IAChE,MAAM,uBAAuB,GAAG,gBAAgB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE3E,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;QACpC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;QAC3C,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,MAAM,QAAQ,EAAE,CAAC;IAEjB,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,uBAAuB,EAAE,CAAC;QAC1B,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9B,WAAW,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC;IAEF,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEpC,MAAM,SAAS,EAAE,CAAC;IAClB,iFAAiF;IACjF,uBAAuB,EAAE,CAAC;AAC5B,CAAC,CAAC"}
1
+ {"version":3,"file":"poller.js","sourceRoot":"","sources":["../src/poller.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ const config = {
9
9
  daemonToken: 'daemon-token',
10
10
  apiUrl: 'https://api.example',
11
11
  pollingIntervalMs: 5000,
12
+ maxPollingIntervalMs: 12_000,
12
13
  timeoutMs: 1000,
13
14
  idleTimeoutMs: 500,
14
15
  runnerCmd: 'opencode',
@@ -61,6 +62,21 @@ const makeClient = (overrides = {}) => ({
61
62
  notifyUpdate: overrides.notifyUpdate ?? (async () => undefined),
62
63
  ackRestartRequest: overrides.ackRestartRequest ?? (async () => undefined),
63
64
  });
65
+ // setTimeout 주입 목: 예약된 폴 콜백과 delay를 캡처해 수동으로 구동한다.
66
+ // 자기예약 루프는 매 cycle 완료 후 새 timeout을 예약하므로, 다음 폴은 scheduled의
67
+ // 마지막 항목을 fire하면 된다.
68
+ const createTimeoutRecorder = () => {
69
+ const scheduled = [];
70
+ const cleared = [];
71
+ const setTimeoutMock = ((callback, delayMs) => {
72
+ scheduled.push({ callback, delayMs: delayMs ?? 0 });
73
+ return { ref() { }, unref() { } };
74
+ });
75
+ const clearTimeoutMock = ((handle) => {
76
+ cleared.push(handle);
77
+ });
78
+ return { scheduled, cleared, setTimeoutMock, clearTimeoutMock };
79
+ };
64
80
  const createRecordingBlocker = () => {
65
81
  const events = [];
66
82
  return {
@@ -79,7 +95,7 @@ test('startPolling handles a claimed trigger, registers auth paths, and runs sch
79
95
  infos.push({ message, meta });
80
96
  });
81
97
  const signals = new Map();
82
- const intervalCallbacks = [];
98
+ const timeouts = createTimeoutRecorder();
83
99
  const cleanupCalls = [];
84
100
  const handledTriggers = [];
85
101
  const savedAuthPaths = [];
@@ -101,11 +117,8 @@ test('startPolling handles a claimed trigger, registers auth paths, and runs sch
101
117
  cleanupCalls.push(authPath);
102
118
  },
103
119
  runConventionSync: async () => undefined,
104
- setInterval: ((callback) => {
105
- intervalCallbacks.push(callback);
106
- return { ref() { }, unref() { } };
107
- }),
108
- clearInterval: (() => undefined),
120
+ setTimeout: timeouts.setTimeoutMock,
121
+ clearTimeout: timeouts.clearTimeoutMock,
109
122
  processOn: ((event, listener) => {
110
123
  signals.set(event, listener);
111
124
  }),
@@ -125,9 +138,11 @@ test('startPolling handles a claimed trigger, registers auth paths, and runs sch
125
138
  await new Promise((resolve) => setImmediate(resolve));
126
139
  assert.deepEqual(handledTriggers, ['trigger-1']);
127
140
  assert.deepEqual(cleanupCalls, []);
128
- assert.equal(intervalCallbacks.length, 1);
141
+ assert.equal(timeouts.scheduled.length, 1);
142
+ // 부트스트랩 cycle에서 트리거를 처리했으므로 다음 폴은 base 간격으로 예약된다.
143
+ assert.equal(timeouts.scheduled[0]?.delayMs, config.pollingIntervalMs);
129
144
  nowValue = 24 * 60 * 60 * 1000 + 1;
130
- await intervalCallbacks[0]?.();
145
+ timeouts.scheduled[0]?.callback();
131
146
  await new Promise((resolve) => setImmediate(resolve));
132
147
  assert.deepEqual(cleanupCalls, ['/auth/path']);
133
148
  assert.deepEqual(savedAuthPaths, ['/auth/path']);
@@ -186,8 +201,8 @@ test('startPolling processes orphaned cancel, worktree removal, and pending clai
186
201
  // 워크트리 경로가 매칭되지 않도록 존재하지 않는 authPath를 사용 → 멱등 제거 완료 경로.
187
202
  loadAuthPaths: () => ['/nonexistent/auth/path'],
188
203
  saveAuthPath: () => '/tmp/auth-paths.json',
189
- setInterval: (() => ({ ref() { }, unref() { } })),
190
- clearInterval: (() => undefined),
204
+ setTimeout: (() => ({ ref() { }, unref() { } })),
205
+ clearTimeout: (() => undefined),
191
206
  processOn: (() => undefined),
192
207
  processExit: (() => {
193
208
  throw new Error('should not exit');
@@ -211,7 +226,7 @@ test('startPolling processes orphaned cancel, worktree removal, and pending clai
211
226
  await pollingPromise;
212
227
  });
213
228
  test('startPolling runs convention sync per auth path every 6 hours', async () => {
214
- const intervalCallbacks = [];
229
+ const timeouts = createTimeoutRecorder();
215
230
  const conventionSyncCalls = [];
216
231
  let nowValue = 6 * 60 * 60 * 1000 + 1;
217
232
  let keepAliveResolve = null;
@@ -222,11 +237,8 @@ test('startPolling runs convention sync per auth path every 6 hours', async () =
222
237
  conventionSyncCalls.push(authPath);
223
238
  },
224
239
  maybeAutoUpdate: async () => ({ cliUpdated: false, runnerUpdated: false }),
225
- setInterval: ((callback) => {
226
- intervalCallbacks.push(callback);
227
- return { ref() { }, unref() { } };
228
- }),
229
- clearInterval: (() => undefined),
240
+ setTimeout: timeouts.setTimeoutMock,
241
+ clearTimeout: timeouts.clearTimeoutMock,
230
242
  processOn: (() => undefined),
231
243
  processExit: (() => {
232
244
  throw new Error('should not exit');
@@ -240,13 +252,13 @@ test('startPolling runs convention sync per auth path every 6 hours', async () =
240
252
  });
241
253
  await new Promise((resolve) => setImmediate(resolve));
242
254
  assert.deepEqual(conventionSyncCalls, ['/auth/path']);
243
- assert.equal(intervalCallbacks.length, 1);
255
+ assert.equal(timeouts.scheduled.length, 1);
244
256
  nowValue += 6 * 60 * 60 * 1000 - 1;
245
- await intervalCallbacks[0]?.();
257
+ timeouts.scheduled.at(-1)?.callback();
246
258
  await new Promise((resolve) => setImmediate(resolve));
247
259
  assert.deepEqual(conventionSyncCalls, ['/auth/path']);
248
260
  nowValue += 1;
249
- await intervalCallbacks[0]?.();
261
+ timeouts.scheduled.at(-1)?.callback();
250
262
  await new Promise((resolve) => setImmediate(resolve));
251
263
  assert.deepEqual(conventionSyncCalls, ['/auth/path', '/auth/path']);
252
264
  const resolveKeepAlive = keepAliveResolve ??
@@ -256,30 +268,36 @@ test('startPolling runs convention sync per auth path every 6 hours', async () =
256
268
  resolveKeepAlive();
257
269
  await pollingPromise;
258
270
  });
259
- test('startPolling logs conflicts and suppresses overlapping polling cycles', async () => {
271
+ test('startPolling logs conflicts and suppresses overlapping polling cycles without double-scheduling', async () => {
260
272
  const infos = [];
261
273
  mock.method(logger, 'info', (message, meta) => {
262
274
  infos.push({ message, meta });
263
275
  });
276
+ // 부트스트랩 cycle은 즉시 idle로 완료시키고, 두 번째 cycle의 fetch를 행 걸어
277
+ // 그 사이 재진입(pollOnce 중복 호출)이 억제되는지 확인한다.
278
+ let fetchCalls = 0;
264
279
  let releaseFetch = null;
265
280
  const client = makeClient({
266
- fetchPollState: async () => await new Promise((resolve) => {
267
- releaseFetch = () => resolve(pollState({ pendingTrigger: trigger }));
268
- }),
281
+ fetchPollState: async () => {
282
+ fetchCalls += 1;
283
+ if (fetchCalls === 1) {
284
+ return pollState();
285
+ }
286
+ return await new Promise((resolve) => {
287
+ releaseFetch = () => resolve(pollState({ pendingTrigger: trigger }));
288
+ });
289
+ },
269
290
  claimTrigger: async () => ({ ok: false, conflict: true }),
270
291
  });
271
- const intervalCallbacks = [];
292
+ const timeouts = createTimeoutRecorder();
272
293
  let keepAliveResolve = null;
273
294
  const pollingPromise = startPolling(config, () => async () => {
274
295
  throw new Error('handler should not run');
275
296
  }, {
276
297
  createClient: () => client,
277
298
  runCleanup: async () => undefined,
278
- setInterval: ((callback) => {
279
- intervalCallbacks.push(callback);
280
- return {};
281
- }),
282
- clearInterval: (() => undefined),
299
+ setTimeout: timeouts.setTimeoutMock,
300
+ clearTimeout: timeouts.clearTimeoutMock,
283
301
  processOn: (() => undefined),
284
302
  processExit: (() => {
285
303
  throw new Error('should not exit');
@@ -292,7 +310,13 @@ test('startPolling logs conflicts and suppresses overlapping polling cycles', as
292
310
  }),
293
311
  });
294
312
  await new Promise((resolve) => setImmediate(resolve));
295
- await intervalCallbacks[0]?.();
313
+ assert.equal(timeouts.scheduled.length, 1, 'bootstrap cycle should schedule the next poll');
314
+ // 두 번째 cycle 시작(fetch 행) 후 같은 콜백을 한 번 더 fire → 재진입 억제.
315
+ timeouts.scheduled[0]?.callback();
316
+ await new Promise((resolve) => setImmediate(resolve));
317
+ timeouts.scheduled[0]?.callback();
318
+ await new Promise((resolve) => setImmediate(resolve));
319
+ assert.equal(timeouts.scheduled.length, 1, 'suppressed overlapping cycle must not schedule another poll');
296
320
  const releasePendingFetch = releaseFetch ??
297
321
  (() => {
298
322
  throw new Error('fetch release was not registered');
@@ -300,6 +324,9 @@ test('startPolling logs conflicts and suppresses overlapping polling cycles', as
300
324
  releasePendingFetch();
301
325
  await new Promise((resolve) => setImmediate(resolve));
302
326
  assert.equal(infos.some((entry) => entry.message === 'Trigger already claimed by another daemon'), true);
327
+ // 행 걸렸던 cycle이 완료되면서 다음 폴 1개만 예약되고, pending 트리거를 봤으므로 base 간격이다.
328
+ assert.equal(timeouts.scheduled.length, 2, 'the in-flight cycle owns scheduling the next poll');
329
+ assert.equal(timeouts.scheduled[1]?.delayMs, config.pollingIntervalMs);
303
330
  const resolveKeepAlive = keepAliveResolve ??
304
331
  (() => {
305
332
  throw new Error('keepAlive resolver was not registered');
@@ -307,17 +334,17 @@ test('startPolling logs conflicts and suppresses overlapping polling cycles', as
307
334
  resolveKeepAlive();
308
335
  await pollingPromise;
309
336
  });
310
- test('startPolling clears the interval and exits on shutdown signals', async () => {
337
+ test('startPolling clears the pending poll timer and exits on shutdown signals', async () => {
311
338
  const signals = new Map();
312
339
  const cleared = [];
313
340
  let keepAliveResolve = null;
314
341
  let exitCode = null;
315
- const intervalHandle = {};
342
+ const timeoutHandle = {};
316
343
  const pollingPromise = startPolling(config, () => async () => undefined, {
317
344
  createClient: () => makeClient(),
318
345
  runCleanup: async () => undefined,
319
- setInterval: (() => intervalHandle),
320
- clearInterval: ((handle) => {
346
+ setTimeout: (() => timeoutHandle),
347
+ clearTimeout: ((handle) => {
321
348
  cleared.push(handle);
322
349
  }),
323
350
  processOn: ((event, listener) => {
@@ -344,7 +371,7 @@ test('startPolling clears the interval and exits on shutdown signals', async ()
344
371
  assert.ok(sigterm);
345
372
  sigterm();
346
373
  assert.equal(exitCode, 0);
347
- assert.deepEqual(cleared, [intervalHandle]);
374
+ assert.deepEqual(cleared, [timeoutHandle]);
348
375
  const resolveKeepAlive = keepAliveResolve ??
349
376
  (() => {
350
377
  throw new Error('keepAlive resolver was not registered');
@@ -364,8 +391,8 @@ test('startPolling delegates auto-update via injected dependency', async () => {
364
391
  autoUpdateCallCount++;
365
392
  return { cliUpdated: false, runnerUpdated: false };
366
393
  },
367
- setInterval: (() => ({})),
368
- clearInterval: (() => undefined),
394
+ setTimeout: (() => ({})),
395
+ clearTimeout: (() => undefined),
369
396
  processOn: (() => undefined),
370
397
  processExit: (() => undefined),
371
398
  now: () => 0,
@@ -411,8 +438,8 @@ test('startPolling restores persisted auth paths for worktree removals after res
411
438
  removeWorktree: (authPath, worktreePath, worktreeId) => {
412
439
  removedWorktrees.push({ authPath, worktreePath, worktreeId });
413
440
  },
414
- setInterval: (() => ({ ref() { }, unref() { } })),
415
- clearInterval: (() => undefined),
441
+ setTimeout: (() => ({ ref() { }, unref() { } })),
442
+ clearTimeout: (() => undefined),
416
443
  processOn: (() => undefined),
417
444
  processExit: (() => {
418
445
  throw new Error('should not exit');
@@ -462,8 +489,8 @@ test('startPolling reports REMOVED when no persisted auth path matches the workt
462
489
  removeWorktree: () => {
463
490
  throw new Error('removeWorktree should not be called');
464
491
  },
465
- setInterval: (() => ({ ref() { }, unref() { } })),
466
- clearInterval: (() => undefined),
492
+ setTimeout: (() => ({ ref() { }, unref() { } })),
493
+ clearTimeout: (() => undefined),
467
494
  processOn: (() => undefined),
468
495
  processExit: (() => {
469
496
  throw new Error('should not exit');
@@ -516,8 +543,8 @@ test('startPolling reports FAILED when worktree removal throws after matching a
516
543
  removeWorktree: () => {
517
544
  throw new Error('permission denied');
518
545
  },
519
- setInterval: (() => ({ ref() { }, unref() { } })),
520
- clearInterval: (() => undefined),
546
+ setTimeout: (() => ({ ref() { }, unref() { } })),
547
+ clearTimeout: (() => undefined),
521
548
  processOn: (() => undefined),
522
549
  processExit: (() => {
523
550
  throw new Error('should not exit');
@@ -563,8 +590,8 @@ test('startPolling acks and runs restart when meta.restartRequested is true with
563
590
  executeRestartRequest: () => {
564
591
  restartCalled += 1;
565
592
  },
566
- setInterval: (() => ({})),
567
- clearInterval: (() => undefined),
593
+ setTimeout: (() => ({})),
594
+ clearTimeout: (() => undefined),
568
595
  processOn: (() => undefined),
569
596
  processExit: (() => undefined),
570
597
  now: () => 0,
@@ -606,8 +633,8 @@ test('startPolling restarts even when a pending trigger is present, ignoring the
606
633
  executeRestartRequest: () => {
607
634
  restartCalled += 1;
608
635
  },
609
- setInterval: (() => ({})),
610
- clearInterval: (() => undefined),
636
+ setTimeout: (() => ({})),
637
+ clearTimeout: (() => undefined),
611
638
  processOn: (() => undefined),
612
639
  processExit: (() => undefined),
613
640
  now: () => 0,
@@ -642,8 +669,8 @@ test('startPolling skips restart and leaves the flag for retry when ack fails',
642
669
  executeRestartRequest: () => {
643
670
  restartCalled += 1;
644
671
  },
645
- setInterval: (() => ({})),
646
- clearInterval: (() => undefined),
672
+ setTimeout: (() => ({})),
673
+ clearTimeout: (() => undefined),
647
674
  processOn: (() => undefined),
648
675
  processExit: (() => undefined),
649
676
  now: () => 0,
@@ -669,8 +696,8 @@ test('startPolling acquires the power save blocker on start and releases it on s
669
696
  const pollingPromise = startPolling(config, () => async () => undefined, {
670
697
  createClient: () => makeClient(),
671
698
  runCleanup: async () => undefined,
672
- setInterval: (() => ({})),
673
- clearInterval: (() => undefined),
699
+ setTimeout: (() => ({})),
700
+ clearTimeout: (() => undefined),
674
701
  processOn: ((event, listener) => {
675
702
  signals.set(event, listener);
676
703
  }),
@@ -702,8 +729,8 @@ test('startPolling releases the power save blocker when keepAlive resolves', asy
702
729
  const pollingPromise = startPolling(config, () => async () => undefined, {
703
730
  createClient: () => makeClient(),
704
731
  runCleanup: async () => undefined,
705
- setInterval: (() => ({})),
706
- clearInterval: (() => undefined),
732
+ setTimeout: (() => ({})),
733
+ clearTimeout: (() => undefined),
707
734
  processOn: (() => undefined),
708
735
  processExit: (() => undefined),
709
736
  now: () => 0,
@@ -724,4 +751,111 @@ test('startPolling releases the power save blocker when keepAlive resolves', asy
724
751
  await pollingPromise;
725
752
  assert.deepEqual(events, ['acquire:daemon-polling', 'release:daemon-polling'], 'blocker should be released after keepAlive resolves');
726
753
  });
754
+ // idle 백오프 테스트 공통 의존성. 폴 스케줄만 관찰하고 나머지는 no-op으로 둔다.
755
+ const backoffDependencies = (timeouts, keepAlive) => ({
756
+ runCleanup: async () => undefined,
757
+ runConventionSync: async () => undefined,
758
+ maybeAutoUpdate: async () => ({ cliUpdated: false, runnerUpdated: false }),
759
+ setTimeout: timeouts.setTimeoutMock,
760
+ clearTimeout: timeouts.clearTimeoutMock,
761
+ processOn: (() => undefined),
762
+ processExit: (() => {
763
+ throw new Error('should not exit');
764
+ }),
765
+ now: () => 0,
766
+ loadAuthPaths: () => [],
767
+ saveAuthPath: () => '/tmp/auth-paths.json',
768
+ keepAlive,
769
+ });
770
+ test('startPolling backs off the poll interval while idle and clamps at maxPollingIntervalMs', async () => {
771
+ const timeouts = createTimeoutRecorder();
772
+ let keepAliveResolve = null;
773
+ const pollingPromise = startPolling(config, () => async () => undefined, {
774
+ createClient: () => makeClient(),
775
+ ...backoffDependencies(timeouts, () => new Promise((resolve) => {
776
+ keepAliveResolve = resolve;
777
+ })),
778
+ });
779
+ // base 5000 / max 12000: idle 연속 시 5000×(1+n×0.5) → 7500, 10000, 12500→12000 clamp.
780
+ await new Promise((resolve) => setImmediate(resolve));
781
+ assert.equal(timeouts.scheduled.length, 1);
782
+ assert.equal(timeouts.scheduled[0]?.delayMs, 7500);
783
+ timeouts.scheduled.at(-1)?.callback();
784
+ await new Promise((resolve) => setImmediate(resolve));
785
+ assert.equal(timeouts.scheduled[1]?.delayMs, 10_000);
786
+ timeouts.scheduled.at(-1)?.callback();
787
+ await new Promise((resolve) => setImmediate(resolve));
788
+ assert.equal(timeouts.scheduled[2]?.delayMs, 12_000, 'delay should clamp at maxPollingIntervalMs');
789
+ timeouts.scheduled.at(-1)?.callback();
790
+ await new Promise((resolve) => setImmediate(resolve));
791
+ assert.equal(timeouts.scheduled[3]?.delayMs, 12_000, 'delay should stay clamped while idle continues');
792
+ const resolveKeepAlive = keepAliveResolve ??
793
+ (() => {
794
+ throw new Error('keepAlive resolver was not registered');
795
+ });
796
+ resolveKeepAlive();
797
+ await pollingPromise;
798
+ });
799
+ test('startPolling resets the poll interval to base after an active cycle', async () => {
800
+ const timeouts = createTimeoutRecorder();
801
+ let keepAliveResolve = null;
802
+ // 폴 순서: idle → idle → pending 트리거(활동) → idle.
803
+ const responses = [pollState(), pollState(), pollState({ pendingTrigger: trigger }), pollState()];
804
+ const client = makeClient({
805
+ fetchPollState: async () => responses.shift() ?? pollState(),
806
+ });
807
+ const pollingPromise = startPolling(config, () => async () => undefined, {
808
+ createClient: () => client,
809
+ ...backoffDependencies(timeouts, () => new Promise((resolve) => {
810
+ keepAliveResolve = resolve;
811
+ })),
812
+ });
813
+ await new Promise((resolve) => setImmediate(resolve));
814
+ timeouts.scheduled.at(-1)?.callback();
815
+ await new Promise((resolve) => setImmediate(resolve));
816
+ timeouts.scheduled.at(-1)?.callback();
817
+ await new Promise((resolve) => setImmediate(resolve));
818
+ timeouts.scheduled.at(-1)?.callback();
819
+ await new Promise((resolve) => setImmediate(resolve));
820
+ assert.deepEqual(timeouts.scheduled.map((entry) => entry.delayMs),
821
+ // idle 백오프(7500→10000) → 활동 시 base(5000) 리셋 → idle streak 처음부터(7500).
822
+ [7500, 10_000, 5000, 7500]);
823
+ const resolveKeepAlive = keepAliveResolve ??
824
+ (() => {
825
+ throw new Error('keepAlive resolver was not registered');
826
+ });
827
+ resolveKeepAlive();
828
+ await pollingPromise;
829
+ });
830
+ test('startPolling stops scheduling new polls after shutdown', async () => {
831
+ const timeouts = createTimeoutRecorder();
832
+ const signals = new Map();
833
+ let keepAliveResolve = null;
834
+ const pollingPromise = startPolling(config, () => async () => undefined, {
835
+ createClient: () => makeClient(),
836
+ ...backoffDependencies(timeouts, () => new Promise((resolve) => {
837
+ keepAliveResolve = resolve;
838
+ })),
839
+ processOn: ((event, listener) => {
840
+ signals.set(event, listener);
841
+ }),
842
+ processExit: (() => undefined),
843
+ });
844
+ await new Promise((resolve) => setImmediate(resolve));
845
+ assert.equal(timeouts.scheduled.length, 1);
846
+ const sigterm = signals.get('SIGTERM');
847
+ assert.ok(sigterm);
848
+ sigterm();
849
+ assert.equal(timeouts.cleared.length, 1, 'pending poll timer should be cleared on shutdown');
850
+ // 셧다운 이후 잔여 타이머 콜백이 fire되어도 새 폴을 예약하지 않는다.
851
+ timeouts.scheduled[0]?.callback();
852
+ await new Promise((resolve) => setImmediate(resolve));
853
+ assert.equal(timeouts.scheduled.length, 1, 'no new poll may be scheduled after shutdown');
854
+ const resolveKeepAlive = keepAliveResolve ??
855
+ (() => {
856
+ throw new Error('keepAlive resolver was not registered');
857
+ });
858
+ resolveKeepAlive();
859
+ await pollingPromise;
860
+ });
727
861
  //# sourceMappingURL=poller.test.js.map