Back-to-back missions: relay re-arms on rejoin (no Stop/Start needed)
Field report: after a mission timed out normally, relaunching a mission did nothing. The relay was single-mission -- once it fired a launch (launches_sent==2) it never re-armed. Fix (operator-side only; the BINARY needs nothing -- a rejoined pod is a brand-new process at WaitingForLaunch): - btconsole _check_launch_gate: when a previous mission finished (launches_sent==2) and ALL seats have RE-ACKED (every pod exited, re-ran join.bat, reconnected), reset the launch state and re-print 'WAITING FOR OPERATOR LAUNCH'. Only reachable on a pod ACK (never mid-mission). Launch is CONSUMED after RunMission #2 (launch_at=None, launch_requested=False) so the next press is a deliberate new round. - btoperator SessionMonitor: reset on each new 'WAITING FOR OPERATOR' so the LAUNCH button RE-ENABLES for mission 2 (it stayed disabled forever before -- the other half of the bug). Verified e2e: two full missions on ONE relay session -- mission 1 runs + times out on the clock, pods rejoin, relay re-arms + re-announces ready, operator LAUNCH -> mission 2's RunMission #1/#2 fire (total fires 2) -> pods running. BACK-TO-BACK PASS. Friends' zip unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
0b83d71578
commit
9252ce92d4
@@ -414,6 +414,26 @@ class Relay:
|
||||
return sum(1 for c in self.console_conns if c.acked)
|
||||
|
||||
def _check_launch_gate(self):
|
||||
# BACK-TO-BACK MISSIONS (2026-07-18): a previous mission finished
|
||||
# (launches_sent==2) and now all seats have RE-ACKED -- i.e. every pod
|
||||
# exited, re-ran join.bat, and reconnected fresh. Reset the launch
|
||||
# state so the relay (and the operator's LAUNCH button) re-arm for a
|
||||
# new round -- no Stop/Start needed. The binary needs nothing: a
|
||||
# rejoined pod is a brand-new process at WaitingForLaunch. (Only ever
|
||||
# reached on a pod ACK, which never happens mid-mission.)
|
||||
if self.launches_sent >= 2 and self._pods_ready() >= len(self.roster):
|
||||
print("[relay] all seats rejoined after the last mission -- "
|
||||
"re-arming for a NEW mission", flush=True)
|
||||
self.launches_sent = 0
|
||||
self.stop_sent = False
|
||||
self.stop_requested = False
|
||||
self.mission_started_at = None
|
||||
self.launch_at = None
|
||||
self.launch_requested = False
|
||||
self._launch_blocked_warned = False
|
||||
self.eggs_done_at = None
|
||||
# fall through -> the normal gate re-prints WAITING FOR OPERATOR
|
||||
|
||||
# GLOBAL launch: arm the timer when the LAST pod has ACKED its egg
|
||||
# (auto mode), or wait for the operator's 'launch' command (manual
|
||||
# mode -- the operator app's Launch button writes it to our stdin).
|
||||
@@ -522,6 +542,11 @@ class Relay:
|
||||
f"{len(self.console_conns)} pod(s)", flush=True)
|
||||
if self.launches_sent == 2:
|
||||
self.mission_started_at = time.time()
|
||||
# CONSUME the launch: clear the timer + the request so the NEXT
|
||||
# LAUNCH press is a fresh, deliberate new-mission request (else the
|
||||
# back-to-back block would re-fire while this mission is running).
|
||||
self.launch_at = None
|
||||
self.launch_requested = False
|
||||
if self.mission_length > 0:
|
||||
print(f"[relay] mission clock: {self.mission_length:.0f}s "
|
||||
"(StopMission at expiry)", flush=True)
|
||||
|
||||
@@ -85,7 +85,12 @@ class SessionMonitor:
|
||||
self.eggs = int(m.group(1))
|
||||
changed = True
|
||||
if self.RE_RELAY_READY.search(line):
|
||||
# WAITING FOR OPERATOR = pods are ready to launch. Reset
|
||||
# `launched` so the LAUNCH button re-enables -- this fires
|
||||
# again for a NEW mission after the pods rejoin (back-to-back
|
||||
# missions, 2026-07-18), not only the first time.
|
||||
self.ready = True
|
||||
self.launched = False
|
||||
changed = True
|
||||
m = self.RE_RELAY_REG.search(line)
|
||||
if m:
|
||||
|
||||
Reference in New Issue
Block a user