


























@@ -37,6 +37,7 @@ let pendingRestartTimer: ReturnType<typeof setTimeout> | null = null;
3737let pendingRestartDueAt = 0;
3838let pendingRestartReason: string | undefined;
3939let pendingRestartEmitHooks: RestartEmitHooks | undefined;
40+let pendingRestartPreparing = false;
4041const activeDeferralPolls = new Set<ReturnType<typeof setInterval>>();
41424243function hasUnconsumedRestartSignal(): boolean {
@@ -51,6 +52,7 @@ function clearPendingScheduledRestart(): void {
5152pendingRestartDueAt = 0;
5253pendingRestartReason = undefined;
5354pendingRestartEmitHooks = undefined;
55+pendingRestartPreparing = false;
5456}
55575658function clearActiveDeferralPolls(): void {
@@ -211,15 +213,34 @@ function updatePendingRestartEmitHooks(hooks?: RestartEmitHooks): void {
211213}
212214213215async function emitPreparedGatewayRestart(hooks?: RestartEmitHooks): Promise<void> {
214-try {
215-await hooks?.beforeEmit?.();
216-} catch (err) {
217-restartLog.warn(`restart preparation failed; restart will continue without it: ${String(err)}`);
216+let nextHooks = hooks ?? pendingRestartEmitHooks;
217+if (!hooks) {
218+pendingRestartEmitHooks = undefined;
219+}
220+let preparedHooks: RestartEmitHooks | undefined;
221+while (nextHooks) {
222+if (preparedHooks) {
223+await preparedHooks.afterEmitRejected?.().catch(() => undefined);
224+preparedHooks = undefined;
225+}
226+try {
227+await nextHooks.beforeEmit?.();
228+preparedHooks = nextHooks;
229+} catch (err) {
230+restartLog.warn(
231+`restart preparation failed; restart will continue without it: ${String(err)}`,
232+);
233+}
234+if (hooks) {
235+break;
236+}
237+nextHooks = pendingRestartEmitHooks;
238+pendingRestartEmitHooks = undefined;
218239}
219240220241const emitted = emitGatewayRestart();
221242if (!emitted) {
222-await hooks?.afterEmitRejected?.().catch(() => undefined);
243+await preparedHooks?.afterEmitRejected?.().catch(() => undefined);
223244}
224245}
225246@@ -478,9 +499,9 @@ export function scheduleGatewaySigusr1Restart(opts?: {
478499};
479500}
480501481-if (pendingRestartTimer) {
482-const remainingMs = Math.max(0, pendingRestartDueAt - nowMs);
483-const shouldPullEarlier = requestedDueAt < pendingRestartDueAt;
502+if (pendingRestartTimer || pendingRestartPreparing) {
503+const remainingMs = pendingRestartPreparing ? 0 : Math.max(0, pendingRestartDueAt - nowMs);
504+const shouldPullEarlier = !pendingRestartPreparing && requestedDueAt < pendingRestartDueAt;
484505if (shouldPullEarlier) {
485506restartLog.warn(
486507`restart request rescheduled earlier reason=${reason ?? "unspecified"} pendingReason=${pendingRestartReason ?? "unspecified"} oldDelayMs=${remainingMs} newDelayMs=${Math.max(0, requestedDueAt - nowMs)} ${formatRestartAudit(opts?.audit)}`,
@@ -512,18 +533,16 @@ export function scheduleGatewaySigusr1Restart(opts?: {
512533pendingRestartTimer = null;
513534pendingRestartDueAt = 0;
514535pendingRestartReason = undefined;
515-const emitHooks = pendingRestartEmitHooks;
516-pendingRestartEmitHooks = undefined;
536+pendingRestartPreparing = true;
517537const pendingCheck = preRestartCheck;
518538if (!pendingCheck) {
519-void emitPreparedGatewayRestart(emitHooks);
539+void emitPreparedGatewayRestart();
520540return;
521541}
522542const cfg = getRuntimeConfig();
523543deferGatewayRestartUntilIdle({
524544getPendingCount: pendingCheck,
525545maxWaitMs: cfg.gateway?.reload?.deferralTimeoutMs,
526- emitHooks,
527546});
528547},
529548Math.max(0, requestedDueAt - nowMs),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。