fix(gateway): resume channel after pending task recovery

This commit is contained in:
openclaw-clownfish[bot]
2026-06-17 22:01:50 +00:00
committed by Ayaan Zaidi
parent 6039da3ed6
commit ecd29fe572
2 changed files with 43 additions and 5 deletions

View File

@@ -456,6 +456,34 @@ describe("channel-health-monitor", () => {
monitor.stop();
});
it("continues pending recovery on the next check without waiting for cooldown", async () => {
const account: Partial<ChannelAccountSnapshot> = disconnectedAccount(Date.now() - 300_000);
const manager = createSnapshotManager(
{
discord: {
default: account,
},
},
{
startChannel: vi.fn(async () => {
account.running = false;
account.connected = false;
account.restartPending = true;
account.reconnectAttempts = 0;
}),
},
);
const monitor = await startAndRunCheck(manager);
expect(manager.stopChannel).toHaveBeenCalledTimes(1);
expect(manager.startChannel).toHaveBeenCalledTimes(1);
await advanceHealthCheck();
expect(manager.stopChannel).toHaveBeenCalledTimes(1);
expect(manager.startChannel).toHaveBeenCalledTimes(2);
monitor.stop();
});
it("caps at 3 health-monitor restarts per channel per hour", async () => {
const manager = createSnapshotManager({
discord: {

View File

@@ -145,12 +145,20 @@ export function startChannelHealthMonitor(deps: ChannelHealthMonitorDeps): Chann
restartsThisHour: [],
};
if (now - record.lastRestartAt <= cooldownMs) {
const continuingPendingRestart =
status.running !== true &&
status.restartPending === true &&
(status.reconnectAttempts ?? 0) === 0;
// A timed-out recovery stop uses the first start request to mark
// restartPending; the next monitor pass must finish that same recovery
// instead of waiting behind this monitor's fresh-restart cooldown.
if (!continuingPendingRestart && now - record.lastRestartAt <= cooldownMs) {
continue;
}
pruneOldRestarts(record, now);
if (record.restartsThisHour.length >= maxRestartsPerHour) {
if (!continuingPendingRestart && record.restartsThisHour.length >= maxRestartsPerHour) {
log.warn?.(
`[${channelId}:${accountId}] health-monitor: hit ${maxRestartsPerHour} restarts/hour limit, skipping`,
);
@@ -161,9 +169,11 @@ export function startChannelHealthMonitor(deps: ChannelHealthMonitorDeps): Chann
log.info?.(`[${channelId}:${accountId}] health-monitor: restarting (reason: ${reason})`);
record.lastRestartAt = now;
record.restartsThisHour.push({ at: now });
restartRecords.set(key, record);
if (!continuingPendingRestart) {
record.lastRestartAt = now;
record.restartsThisHour.push({ at: now });
restartRecords.set(key, record);
}
try {
if (status.running) {