-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Overview
Multiple issues across NodeBridge, PyodideBridge, and HttpBridge relate to inconsistent init/dispose lifecycle handling. This tracking issue proposes a shared lifecycle mixin.
Related Issues
- fix: Track initialization state more robustly in NodeBridge.init() #137 - Track initialization state more robustly in NodeBridge.init()
- PyodideBridge should clear initPromise on init failure to allow retry #116 - PyodideBridge should clear initPromise on init failure to allow retry
- OptimizedNodeBridge should block late worker spawns after dispose #102 - OptimizedNodeBridge should block late worker spawns after dispose
- PyodideBridge dispose should reset initPromise to allow re-init #69 - PyodideBridge dispose should reset initPromise to allow re-init
- NodeBridge dispose should cancel in-flight init to avoid orphaned processes #63 - NodeBridge dispose should cancel in-flight init to avoid orphaned processes
- Pyodide bridge should allow retry after init or package load failures #57 - Pyodide bridge should allow retry after init or package load failures
Proposed Architecture
State Machine
pending → initializing → ready
↓ ↓ ↓
disposed failed disposed
↓
pending (retry)
BridgeLifecycle Mixin
type LifecycleState = 'pending' | 'initializing' | 'ready' | 'failed' | 'disposed';
abstract class BridgeLifecycle {
protected state: LifecycleState = 'pending';
protected initPromise?: Promise<void>;
protected initAbortController?: AbortController;
async init(): Promise<void> {
if (this.state === 'disposed') {
throw new BridgeDisposedError('Bridge has been disposed');
}
if (this.state === 'ready') {
return;
}
if (this.initPromise) {
return this.initPromise;
}
this.state = 'initializing';
this.initAbortController = new AbortController();
this.initPromise = this.doInit(this.initAbortController.signal)
.then(() => { this.state = 'ready'; })
.catch((error) => {
this.state = 'failed';
this.initPromise = undefined; // Allow retry
throw error;
});
return this.initPromise;
}
async dispose(): Promise<void> {
if (this.state === 'disposed') return;
this.state = 'disposed';
this.initAbortController?.abort();
this.initPromise = undefined;
await this.doDispose();
}
protected abstract doInit(signal: AbortSignal): Promise<void>;
protected abstract doDispose(): Promise<void>;
}Acceptance Criteria
- All bridges use consistent lifecycle state machine
- Init failures allow retry (initPromise cleared)
- Dispose cancels in-flight init operations
- Post-dispose operations throw BridgeDisposedError
- Late spawns blocked after dispose
- All 6 related issues can be closed
Scope
This fix touches:
src/runtime/node.ts- NodeBridgesrc/runtime/pyodide.ts- PyodideBridgesrc/runtime/http.ts- HttpBridge- New:
src/runtime/lifecycle.ts- shared mixin
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request