fix: isolate concurrent OpenCode chat runs
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
export type OpencodeLifecycleState = 'stopped' | 'starting' | 'running' | 'error';
|
||||
export type OpencodeRuntimeGenerationProvenance = 'unknown' | 'starting' | 'fresh' | 'attached';
|
||||
|
||||
export interface OpencodeStatus {
|
||||
state: OpencodeLifecycleState;
|
||||
@@ -400,6 +401,7 @@ export class OpencodeManager extends EventEmitter {
|
||||
private cancelStartsBeforeSequence = 0;
|
||||
private runtimeGeneration = 0;
|
||||
private activeRuntimeGeneration: number | null = null;
|
||||
private activeRuntimeGenerationProvenance: OpencodeRuntimeGenerationProvenance = 'unknown';
|
||||
private activeStartAttempt: RuntimeStartAttempt | null = null;
|
||||
private readonly trackedUnreleasedPorts = new Set<number>();
|
||||
private lifecycleBusy = false;
|
||||
@@ -423,6 +425,18 @@ export class OpencodeManager extends EventEmitter {
|
||||
return { ...this.status };
|
||||
}
|
||||
|
||||
getRuntimeGeneration(): number {
|
||||
return this.status.state === 'starting' || this.status.state === 'running'
|
||||
? this.activeRuntimeGeneration ?? 0
|
||||
: 0;
|
||||
}
|
||||
|
||||
getRuntimeGenerationProvenance(): OpencodeRuntimeGenerationProvenance {
|
||||
return this.status.state === 'starting' || this.status.state === 'running'
|
||||
? this.activeRuntimeGenerationProvenance
|
||||
: 'unknown';
|
||||
}
|
||||
|
||||
getManagedConfigDir(): string | null {
|
||||
const userDataDir = this.options.userDataDir?.trim();
|
||||
return userDataDir ? getManagedOpencodeConfigDir(userDataDir) : null;
|
||||
@@ -518,6 +532,7 @@ export class OpencodeManager extends EventEmitter {
|
||||
}
|
||||
if (this.activeRuntimeGeneration === generation) {
|
||||
this.activeRuntimeGeneration = null;
|
||||
this.activeRuntimeGenerationProvenance = 'unknown';
|
||||
}
|
||||
this.setStatus({ state: 'stopped', port: this.options.port });
|
||||
} catch (error) {
|
||||
@@ -685,6 +700,7 @@ export class OpencodeManager extends EventEmitter {
|
||||
if (!listeningPort) return;
|
||||
|
||||
finish(() => {
|
||||
this.activeRuntimeGenerationProvenance = 'fresh';
|
||||
this.setStatus({
|
||||
state: 'running',
|
||||
port: listeningPort,
|
||||
@@ -738,6 +754,7 @@ export class OpencodeManager extends EventEmitter {
|
||||
url: existingServer.url,
|
||||
},
|
||||
);
|
||||
this.activeRuntimeGenerationProvenance = 'attached';
|
||||
this.setStatus(existingServer);
|
||||
resolve(this.getStatus());
|
||||
});
|
||||
@@ -805,6 +822,7 @@ export class OpencodeManager extends EventEmitter {
|
||||
controller: new AbortController(),
|
||||
};
|
||||
this.activeRuntimeGeneration = attempt.generation;
|
||||
this.activeRuntimeGenerationProvenance = 'starting';
|
||||
this.activeStartAttempt = attempt;
|
||||
return attempt;
|
||||
}
|
||||
@@ -997,6 +1015,7 @@ export class OpencodeManager extends EventEmitter {
|
||||
this.recordPortReleaseOutcome(port, true, released);
|
||||
if (released) {
|
||||
this.activeRuntimeGeneration = null;
|
||||
this.activeRuntimeGenerationProvenance = 'unknown';
|
||||
this.setStatus({
|
||||
state: 'stopped',
|
||||
port: this.options.port,
|
||||
|
||||
Reference in New Issue
Block a user