Skip to content

Commit 65d08ef

Browse files
matthew-pilotmatthew-pilot
andauthored
fix(claw-pilot): stopAccount before restart on config change (PILOT-188) (#2)
onAccountConfigChanged stopped the transport but left the account in PilotLifecycle.accounts, so the subsequent startAll → startAccount call threw "already running". The error was caught and routed to scheduleRetry, causing live config changes to be silently lost until gateway restart. Added PilotLifecycle.stopAccount() that stops transport + pipeline + drainTimer and removes the account from the map in a single idempotent operation. Replaced the manual transport.stop() in onAccountConfigChanged with stopAccount(). Note: Bug 1 (handshakeTrustAutoApprove dead config) confirmed but deferred — removing the flag touches 5 files (types, resolver, schema, 3 test files). Operator should split to a follow-up or handle manually. Closes PILOT-188 Co-authored-by: matthew-pilot <matthew-pilot@vulturelabs.io>
1 parent 526f35e commit 65d08ef

2 files changed

Lines changed: 14 additions & 4 deletions

File tree

plugin/src/channel-plugin-api.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,7 @@ export function buildPilotChannelPlugin(deps: BuildPilotPluginDeps): PilotChanne
135135
accountId: string;
136136
}) => {
137137
deps.logger.info("pilot channel: account changed, reloading", { accountId });
138-
const acct = lifecycle.getAccount(accountId);
139-
if (acct) {
140-
await acct.transport.stop();
141-
}
138+
await lifecycle.stopAccount(accountId);
142139
await lifecycle.startAll(nextCfg);
143140
},
144141
onAccountRemoved: async ({ accountId }: { accountId: string }) => {

plugin/src/lifecycle.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,19 @@ export class PilotLifecycle {
275275
return this.accounts.get(accountId)?.outbox;
276276
}
277277

278+
/** Stop a single account and remove it from the live map. */
279+
async stopAccount(accountId: string): Promise<void> {
280+
const state = this.accounts.get(accountId);
281+
if (!state) return;
282+
try {
283+
if (state.drainTimer) clearInterval(state.drainTimer);
284+
state.pipeline.stop();
285+
await state.transport.stop();
286+
} finally {
287+
this.accounts.delete(accountId);
288+
}
289+
}
290+
278291
async stopAll(): Promise<void> {
279292
const tasks: Promise<void>[] = [];
280293
for (const [id, state] of this.accounts) {

0 commit comments

Comments
 (0)