@@ -175,69 +175,49 @@ def ensure_daemon_running(interpreter_paths: list) -> bool:
175175 are adopted so the daemon registry sees them on startup.
176176 """
177177 try :
178- from omnipkg .isolation .worker_daemon import DaemonClient , DAEMON_LOG_FILE
178+ from omnipkg .isolation .worker_daemon import DaemonClient , PID_FILE
179179 client = DaemonClient ()
180180 status = client .status ()
181181
182182 if status .get ("success" ):
183183 safe_print (" ✅ Daemon already running" )
184184 else :
185185 safe_print (" 🔄 Starting daemon (all pythons already adopted)..." )
186- _daemon_start = time .perf_counter ()
187- # On Windows .bat shims require shell=True; capture both streams so
188- # rc=1 failures are visible rather than silently swallowed.
189- _is_win = sys .platform == "win32"
190186 proc = subprocess .Popen (
191187 ["8pkg" , "daemon" , "start" ],
192188 stdout = subprocess .DEVNULL ,
193189 stderr = subprocess .DEVNULL ,
194190 )
195- # Poll until daemon answers, launcher exits with error, or we time out.
196- _came_up = False
197- for i in range (60 ):
198- time .sleep (0.5 )
199- rc = proc .poll ()
200- if rc is not None and rc != 0 :
201- # Launcher exited non-zero — bail immediately, don't burn
202- # the remaining 30s pretending the daemon might appear.
203- try :
204- _out = proc .stdout .read ().decode ("utf-8" , errors = "replace" ).strip ()
205- _err = proc .stderr .read ().decode ("utf-8" , errors = "replace" ).strip ()
206- except Exception :
207- _out = _err = ""
208- safe_print (f" ❌ Launcher exited rc={ rc } — daemon start failed" )
209- if _out :
210- for ln in _out .splitlines ():
211- safe_print (f" [launcher stdout] { ln } " )
212- if _err :
213- for ln in _err .splitlines ():
214- safe_print (f" [launcher stderr] { ln } " )
215- dump_daemon_log ("DAEMON LOG ON FAILURE" , only_on_error = False )
216- return False
217- if rc == 0 and i == 0 :
218- safe_print (" ℹ️ Launcher exited rc=0 — daemon detached" )
219- status = client .status ()
220- if status .get ("success" ):
221- _daemon_elapsed = (time .perf_counter () - _daemon_start ) * 1000
222- safe_print (f" ✅ Daemon up after { format_duration (_daemon_elapsed )} " )
223- _came_up = True
224- # Close pipes so the launcher handle doesn't pin the process
225- try :
226- proc .stdout .close ()
227- proc .stderr .close ()
228- except Exception :
229- pass
191+
192+ # --- NEW ROBUST WAITING LOGIC ---
193+ safe_print (f" ⏳ Waiting for PID file at: { PID_FILE } " )
194+ deadline = time .monotonic () + 60.0 # Wait up to 60 seconds
195+ pid_file_found = False
196+ while time .monotonic () < deadline :
197+ if os .path .exists (PID_FILE ):
198+ safe_print (" ✅ PID file appeared." )
199+ pid_file_found = True
230200 break
231- if not _came_up :
232- safe_print (" ❌ Daemon never came up — killing launcher to unblock CI" )
233- try :
234- proc .kill ()
235- proc .wait (timeout = 5 )
236- except Exception :
237- pass
238- dump_daemon_log ("DAEMON LOG ON FAILURE" , only_on_error = False )
201+ time .sleep (0.5 )
202+
203+ if not pid_file_found :
204+ safe_print (f" ❌ Timed out waiting for PID file after 60s." )
205+ # It's still useful to dump the log if it exists
206+ dump_daemon_log ("DAEMON LOG ON PID TIMEOUT" , only_on_error = False )
239207 return False
240208
209+ # Give it a couple more seconds for the socket to bind after PID is written
210+ time .sleep (2 )
211+
212+ # Now verify connection
213+ status = client .status ()
214+ if status .get ("success" ):
215+ safe_print (" ✅ Daemon confirmed responsive." )
216+ else :
217+ safe_print (" ❌ Daemon started but is not responsive." )
218+ dump_daemon_log ("DAEMON LOG ON FAILURE" , only_on_error = False )
219+ return False
220+
241221 return True
242222
243223 except Exception as e :
0 commit comments