flan/test/programs/dev-lateagent.flan
Joseph Ferano 89481cf8ec The wait for the agent socket was in front of the accept loop
[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.
2026-09-20 18:11:32 +07:00

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)