sak-runner --attach shows a service slot's running view on its host and takes its keys #194
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "task/3665-s1-sak-runner-attach-shows-a-service-run"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Tracker: #3665
A runner that runs as a service slot now keeps the running view's board and serves its view on a Unix socket.
sak-runner --attachshows that view in a terminal on the host, over ssh too, and sends it keys.What it delivers
~/.sak-runner/view.<slot>.sock, which only its user can reach (mode 0600). It opens no network port.sak-runner --attach [--slot a|b]connects to the slot the configuration'sslotline names, or to the one given. It puts its terminal in raw mode, sends its size, each resize and its input, and writes what the runner draws. The pages and keys are the ones a terminal runner shows, drawn byrunner/view.sx. The runner side is a std.tui peer session.d detachis in the footer of every page.d, ctrl-c, the attach's input ending, or its connection dropping end the attach and leave the runner as it was.qasks how to stop, as at a terminal. In an attach, the box sayslaunchd does not restart slot a once it stops(systemd on Linux). The farewell line goes to the attach and to the runner log.runner/view.sxis split intoHost, one per runner (the board, the captured stdout, settling and the stop), andView, one viewer. The board wakes every open view.sak-runner: slot a handed over to slot band attaches to slot b.--attachprintssak-runner: no runner listens on <socket>and exits 1.runner/attach.sx). Each message is a kind byte, a 4-byte length and a payload. The attach sendsz(size) andk(keys). The slot sendso(screen bytes), thend(detached),s(stopped, saying how) orh(handed over, naming the slot).runner/README.mdhas an Attaching section after The console, and the flag paragraph and Tests describe--attachandtests/runner_attach.sx.Tests
tests/runner_attach.sxserves sak in process and runs a slotted runner in process, with its stdout pointed at a file that stands in for the runner log.d, ctrl-c and input ending each detach, and the runner takes a step and holds its steps and channel after;qafter them shows the stop box;h bwhen the runner hands over, ands stopped · …when it is stopped from an attach.srw-------, and the runner log keeps the console lines.dist/sak-runner --attachon a pseudo-terminal: it shows the view, sends ↓, redraws on a resize of its own terminal, follows the hand-over to a stand-in for slot b, and detaches there (exit 0).no runner listens on …and exits 1, for--slot aand for the configuration'sslot=b.tests/runner_handover.sxholdssak-runner --attach --slot aon a pseudo-terminal across the hand-over between real slot processes under its systemd stand-in. The attach follows slot a to slot b, shows slot b's view and detaches there with exit 0.Fail-before. At master
ce44f520the test does not build:cannot read import 'runner/attach.sx'. Mutation arms of895dba9f, each agit archivearm withdist/sak-runnerrebuilt. The first failing check is the pinned one; later failures in an arm cascade from it:dnot detachingchmod 0600finishdropping the slot handed over tohThe existing tests that run a slotted or terminal runner pass at
895dba9f, run throughtests/run.sh:runner_handover(163 s),runner_launchd(100 s, real launchd),runner_view(66 s),runner_install(12 s).Review answers
A size sent after a view ended reached its freed session. When a view ended, its thread closed the attach's peer session, which frees the size a resize stores into and closes the session's signal pipe. Only then did it wait for the view's Flows follower to return from its call to sak. Meanwhile the relay still read the attach's messages, and each size made it resize the closed session: the size went into freed memory, and a byte went to whatever file then held the number of the session's signal pipe. Each attach now has a mutex and a
closedflag. The view's thread sets the flag before it closes the session, and the relay resizes only while the flag is clear.tests/runner_attach.sx: the in-process sak's dispatch holds the GETs of/api/flow-runswhile the test asks. An attach opens its Flows page, so its follower's call is held, then sendsd. The test waits for the number of the session's signal pipe to be free, takes it for a pipe of its own (F_DUPFD_CLOEXEC), sends a size, and checks that its pipe received nothing. Then it lets the call go and checks that the attach is told it detached.runner/attach.sx, 4 runs of 4 failed "a size the attach sends then reaches nothing", and each process then died of SIGTRAP (exit 133) after the freed size was written. With the fix,runner_attachpassed 7 runs of 7.The hand-over through
hold()had no test.tests/runner_handover.sxnow holdssak-runner --attach --slot aon a pseudo-terminal across the hand-over between real slot processes. The client is the installed version file, so its command names the scene's directory. Once the old slot's process exits, the attach sayssak-runner: slot a handed over to slot band shows slot b's view, anddthere ends it withsak-runner: detached from slot b, exit 0.hold()'s line that names the slot handed over to, withdist/sak-runnerrebuilt there, printedRUNNER HANDOVER FAIL (3 checks): "the attach says slot a handed over to slot b", "... and shows slot b's view" and "... whose detach ends the attach". The head passed (RUNNER HANDOVER OK, 158 s).Keys typed while a view was ending held the relay for good (review 1975, F1). The relay wrote each
kmessage to the view's input pipe with a blocking write. Once the view stopped reading, a burst larger than the pipe held the relay in that write. The attach was never told it detached, and the runner's stop and hand-over waited on that relay forever. The same write also wedged a view that was still showing. The relay is the only reader of what the view draws. While it waited for the view to take keys, a view that redrew on each key filled its screen pipe and then stopped taking keys.Fix: keys now wait at the slot in a queue. The relay hands them to the view's input without blocking, only while the pipe has room, and meanwhile keeps reading the view's screen and the attach's messages. When the view ends, its thread closes its input right after closing its session, so keys handed after that fail at once and the relay drops them.
Regressions, in
tests/runner_attach.sx. Both send one burst that is more than the view's input pipe holds: 8192 keys the view redraws on one by one, then a 128 KiB bracketed paste.qshows the stop box.d: once the follower's call returns, the attach is told it detached.RUNNER ATTACH FAILand exits 1 within its 30 s wait.Fail-before and pass-after, from
git archivearms of84eb16bbwith the new test:runner/attach.sxrunner/attach.sx, test without the live burstRUNNER ATTACH OKin 8 s, then 3 runs of 3 OK, 5 s eachThe review's probe sends a 256 KiB
kmessage after "a size the attach sends then reaches nothing". A second probe sends 256 KiB while the view shows. At84eb16bb, each failed its check and then hung untiltimeoutkilled it at 150 s. With the fix, both pass.Not pinned: an arm that leaves the view's input open until the relay closes it after the view's thread ends also passes. The queue alone keeps the relay from blocking. Closing the input at once only stops keys from queuing for a view that takes no more.
The branch also merges master
bc8ec978(#3981) cleanly, so the gates below test the tree Merge would land.Gates at the head
At
587a7d1e, with masterbc8ec978merged in (master has not moved since):full: gate run 995, passed:tests/run.sh: 71 files in 296 s, withrunner_handover159 s andrunner_attach7 s;fast: gate run 992, passed. It ran on the same tree before the commit, so it is recorded at84eb16bb.Earlier rounds: at
84eb16bb,fast984 andfull988 passed; at895dba9f,fast964 andfull967 passed.Left open
On the way, the pinned sx (af8455c3) rejected a
matchthat has areturnorcontinuearm, an arm that discards aboolcall's value, and an empty arm. The error iscannot coerce a value of type 'void' to 'bool'. No SX task covered it; the reproduction is in the step's summary for filing. The code here writes terminal output throughFdWriter, astui.Sessiondoes, so it does not meet that case.