flan/test/programs/dev-lateagent.flan
Joseph Ferano 77d6e43b09 The agent binds before main, so a dev program need not start it at all
A constructor in the agent package binds FLAN_AGENT_SOCKET when it is set,
which is the daemon and nothing else — both shapes set it, before the fork in
--two-process and before the exec in the merged build. So a program under
[flan dev] that calls (agent/poll) and has no (agent/start) in it takes
redefinitions anyway, and one that does call start meets an agent that is
already listening and gets a no-op.

The window this closes was the complaint in DISCUSS.org: a program that opens
a window before starting its agent leaves the daemon waiting on a socket that
does not exist yet. Bound here, the socket exists before main whatever the
program does afterwards — so test_dev.ml's late-agent row asserts the negation
of what it used to. The delivery sent during the sleep no longer carries "the
program has not called (agent/start ...) yet", because that is no longer true
of it; what is still late, and still asserted, is the poll that installs it.

It reaches exactly as far as the linker does. Reach prunes a package nothing
calls into, so a program that mentions the agent nowhere does not link this
file and has no constructor to run: auto-start is for a program that polls and
has dropped its start call, not for one that says nothing about the agent at
all. That limit and the release-build residual are in FIX.org, along with the
daemon branch that can no longer be reached.

agent-nostart.flan is the pin, and its two numbers are the honest ones: 1
before anything could arrive, 1000 after the wait, because a listener bound
before main is still not an install.
2026-09-20 19:52:34 +07:00

43 lines
1.7 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.
;;;;
;;;; The socket is no longer late, only the call is. The package's constructor
;;;; binds it before main when a daemon has said where, so the start below
;;;; arrives at an agent that is already listening and is a no-op answering the
;;;; same socket — which is what makes this fixture the double-start case under
;;;; a real daemon as well.
(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)