Check "exited" against the process record before believing it
A session adopted at a backend start keeps the transcript's last status, so one whose process had been reported gone and was then found again read as `exited` while its CLI was running. `exited` is the word that draws the phone's Start button and lets `start_session` build a driver, so Start was accepted every time it was pressed -- and since starting replaces the driver without retiring the old one, each press left another reader on the same process. Every line the CLI wrote was then translated once per reader: three presses put three interleaved copies of one reply on screen, which is what it was reported as. So `exited` is now checked against `session::process`, the one authority on whether a process exists, in `launch` and again in `start_session`. A record that is not known to be dead makes it false, and what replaces it is `unknown` -- there is a process, and nothing here has heard from it, which is the answer `status_of_unlaunched` already gave to the same question. The correction goes out through the sink rather than into the manager's view alone, or the list and the session screen would disagree about it in the way this same button did a commit ago. A driver that `start_session` replaces now gets `Driver::detach`, which already existed for the backend going away and is the whole of what a driver whose process has exited is owed. On the phone the process button is disabled while its own request is in flight, so a second press cannot be decided against a status the first has not changed yet. That is a courtesy rather than the fix; the server refuses it either way, because a phone that has lost the stream cannot be relied on to know. Verified against a stand-in CLI, with the state forced by hand: before, three Starts returned 204 and left four readers on one process and the status still `exited`; after, the session reports `unknown` on both surfaces and all three are refused. Then driven on the emulator -- Stop, Start, Stop, Start alternated correctly with one process at a time, and the list, the transcript and the record all agree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
558095520d
commit
50f9b956d9
4 files changed
+210
-10
No files matched your search
@@ -351,6 +351,36 @@ better answer until its output says otherwise. Coming from the driver also
|
||||
orders it against the exit `follow` reports, which a status written from the
|
||||
manager could not be.
|
||||
|
||||
**`Exited` is a claim about a process, and the record is what settles it.**
|
||||
Adopting saying nothing left one word standing that a live process
|
||||
contradicts. A session whose process was reported gone and then found again
|
||||
at the next backend start kept `Exited` from the transcript — and `Exited` is
|
||||
the word that draws a Start button. Start was then accepted every time it was
|
||||
pressed, and since starting replaces the driver, each press attached *another*
|
||||
reader to the one process: every line the CLI wrote was translated once per
|
||||
reader, so three presses put three interleaved copies of one reply on screen.
|
||||
Two rules come out of it, and neither is optional:
|
||||
|
||||
- **`Exited` is checked against `session::process` before it is believed** —
|
||||
`corrected`, called in `launch` and again in `start_session`. A record that
|
||||
is not known to be dead makes it false, and what replaces it is `Unknown`:
|
||||
there is a process, and nothing here has heard from it, which is the answer
|
||||
`status_of_unlaunched` already gave to the same question. Every other status
|
||||
is left exactly as it was — those are the pump's, written from what the
|
||||
process itself said, and none of them authorises starting anything. The
|
||||
correction goes out through the sink for the reason above: written into the
|
||||
manager's view alone it would be the list and the screen disagreeing again.
|
||||
- **A driver that is replaced is detached.** Swapping the `Arc` does not end
|
||||
the tasks the old one is running. `Driver::detach` is what does — it already
|
||||
existed for the backend going away — and it is the whole of what a driver
|
||||
whose process has exited is owed.
|
||||
|
||||
The phone's half is that the process button is disabled while its own request
|
||||
is in flight, so a second press cannot be decided against a status the first
|
||||
one has not changed yet. That is a courtesy rather than the fix: the server
|
||||
refuses the second request either way, because a phone that has lost the
|
||||
stream cannot be relied on to know.
|
||||
|
||||
On the phone this is one button in the composer, left of Send, whose mark and
|
||||
colour say what pressing it would do now: an orange pause while a turn is
|
||||
running (interrupt — the process stays), a red stop when it is not (end the
|
||||
|
||||
Reference in new issue
Block a user