[merged_serve] waited up to ten seconds for the program to bind agent.sock before it started [accept_loop]. The listening socket was already up, so an editor connected fine and then heard nothing: every first request of every session cost the whole wait when the program calls (agent/start ...) late — sand.flan starts it after rl/init-window returns — or never. Nothing the editor asks needs that socket. In one process a delivery is a call into flan_agent.c, not a connect, and the two-process daemon has already waited for the bind in [two_process] and fails if it never comes. What the wait was for is the sentence a program with no agent deserves, and a sentence does not have to be in front of the loop to be said. So it is a deadline the session passes ([agent_check]) rather than a wait it does: read from the accept loop between connections and from [serve] before each request, because an editor holds one connection for a whole session and the loop is not cycling while it is attached. No thread, for the reason lib/dune gives about what the merged link does to this library's dependencies. Delivery stays honest either way. A program that links no agent at all refuses through [over_socket]'s ENOENT, as before. One that has the agent but has not started it takes the module into the ring and is answered with a note that promises the poll and not a frame: a program with no (agent/poll) in it never installs this, and "at its next frame boundary" would be the reply that makes a redefinition look applied when it is not. C-x C-e's five-second timeout gets the same distinction instead of asking whether a program that has not got to its loop yet is calling the poll in it. And the note a parked program's delivery carries is now said once per park. A finished program is parked, so re-evaluating while a run's output is on the screen repeated a paragraph on every C-c C-c. The first delivery of each park explains itself; the rest say the one line that is the claim. [rerun] clears the flag as well as [eval] does, so a new park is a new reader.
37 lines
1.4 KiB
Plaintext
37 lines
1.4 KiB
Plaintext
;;;; A program that does call (agent/start ...) — but only after something
|
|
;;;; slow, which is the shape a real one has.
|
|
;;;;
|
|
;;;; sand.flan opens a window first and starts the agent afterwards, so on a
|
|
;;;; machine where window setup takes a while the socket appears seconds into
|
|
;;;; the run. [merged_serve] used to wait up to ten seconds for that socket
|
|
;;;; *before* starting its accept loop, so those seconds were charged to the
|
|
;;;; first thing the editor asked, every session. This fixture is that delay
|
|
;;;; with the window taken out: a sleep, then the agent, then an ordinary
|
|
;;;; poll loop.
|
|
;;;;
|
|
;;;; Two claims are checked against it in test_dev.ml: the session answers
|
|
;;;; while the sleep is still running, and a redefinition sent during the
|
|
;;;; sleep is installed once the program is up.
|
|
(import agent "vendor:agent")
|
|
|
|
(defvar frames i64)
|
|
|
|
(defn step [] i64 7)
|
|
|
|
(defn tick [] i64
|
|
(set frames (+ frames 1))
|
|
frames)
|
|
|
|
(defn main [] i32
|
|
;; Long enough for a test to connect, ask something and evaluate inside it,
|
|
;; and short enough that the rest of the test is not waiting on it.
|
|
(sleep-seconds 3.0)
|
|
(agent/start "/tmp/flan-dev-lateagent-fallback.sock")
|
|
;; dev-chatty.flan's count, for its reason: the test ends the session when
|
|
;; it is done, and a program that ran out of frames first would fail for
|
|
;; the wrong reason.
|
|
(dotimes [i 24000]
|
|
(tick)
|
|
(agent/wait 1))
|
|
0)
|