Skip to content

Commit c87e179

Browse files
refactor: improve engine startup logic by refining PID checks and enhancing health monitoring during disk wait operations
1 parent 1e3d337 commit c87e179

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

dashboard/lib/services/engine_bundled_launcher.dart

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,16 @@ class EngineBundledLauncher {
133133
}
134134

135135
if (!forceRestart) {
136-
// If the dashboard previously wrote "starting" but no PID was ever recorded
137-
// (e.g. first install, app closed quickly, or reboot), waiting a full health
138-
// window just delays startup and can look like a hang.
139-
final shouldWaitForExisting =
140-
cfg.pid != 0 && cfg.status != EngineStatus.stopped;
136+
// Wait for an in-flight or already-up engine on disk. Do not require pid != 0:
137+
// reconciled / external engines may show running with pid 0 until the next
138+
// writer refreshes; HTTP health is the real signal.
139+
final shouldWaitForExisting = cfg.status != EngineStatus.stopped &&
140+
cfg.status != EngineStatus.failed &&
141+
(cfg.pid != 0 ||
142+
cfg.status == EngineStatus.starting ||
143+
cfg.status == EngineStatus.healthChecking ||
144+
cfg.status == EngineStatus.running ||
145+
cfg.status == EngineStatus.restarting);
141146
final diskRunning = shouldWaitForExisting
142147
? await _waitRunningOnDiskWithin(cfg.host, _healthWindow)
143148
: null;
@@ -214,12 +219,15 @@ class EngineBundledLauncher {
214219
);
215220
await EngineConfigStore.writeAtomic(cfg);
216221

217-
final runningCfg =
218-
await _waitRunningOnDiskWithin(cfg.host, _healthWindow);
222+
final runningCfg = await _waitRunningOnDiskWithin(
223+
cfg.host,
224+
_healthWindow,
225+
expectedPid: childPid,
226+
);
219227
if (runningCfg != null &&
220228
runningCfg.status == EngineStatus.running &&
221-
runningCfg.pid == childPid &&
222-
await _strictHealth(runningCfg.host, runningCfg.port)) {
229+
await _strictHealth(runningCfg.host, runningCfg.port) &&
230+
(runningCfg.pid == 0 || runningCfg.pid == childPid)) {
223231
return EngineBootstrapOutcome(
224232
success: true,
225233
activeHost: runningCfg.host,
@@ -283,10 +291,13 @@ class EngineBundledLauncher {
283291
} catch (_) {}
284292
}
285293

294+
/// When [expectedPid] is set and disk has a non-zero pid that differs, keep waiting
295+
/// (stale row). [pid] 0 on disk + healthy HTTP counts as ready (external / reconciled).
286296
static Future<EngineConfig?> _waitRunningOnDiskWithin(
287297
String connectHost,
288-
Duration window,
289-
) async {
298+
Duration window, {
299+
int? expectedPid,
300+
}) async {
290301
final deadline = DateTime.now().add(window);
291302
while (DateTime.now().isBefore(deadline)) {
292303
final disk = await EngineConfigStore.read();
@@ -295,8 +306,13 @@ class EngineBundledLauncher {
295306
}
296307
if (disk != null &&
297308
disk.status == EngineStatus.running &&
298-
disk.pid != 0 &&
299309
await _strictHealth(connectHost, disk.port)) {
310+
if (expectedPid != null &&
311+
disk.pid != 0 &&
312+
disk.pid != expectedPid) {
313+
await Future<void>.delayed(_healthTick);
314+
continue;
315+
}
300316
return disk;
301317
}
302318
await Future<void>.delayed(_healthTick);

0 commit comments

Comments
 (0)