;;;; What a re-run does to a global, which is decided by the form that ;;;; defined it and not by the daemon. ;;;; ;;;; A [defvar] is Common Lisp's [defvar]: its initialiser runs only if the ;;;; variable is not already initialised, so its value survives a re-run. A ;;;; plain zeroed one always did — .bss is untouched by a second entry into ;;;; main — and a computed one did not, because the startup function [main] ;;;; calls ran again from the top and stored the initial value back over ;;;; whatever the last run had left. A [defconst] is a constant and the ;;;; question does not arise. ;;;; ;;;; So each line printed below is a claim about one of those cases, and the ;;;; run number is the first of them: [runs] is computed, so before the fix it ;;;; counted 1, 1, 1. (import agent "vendor:agent") (defconst base i64 40) ;; Computed, and the whole reproduction: the initialiser is a call, so it is ;; lifted into the startup function rather than written into the image. (defn start [] i64 base) (defvar counter i64 (start)) ;; Zero-valued, which needs no startup at all and must keep needing none. (defvar zeroed i64) ;; A computed dyn global: the map is built by a function, rooted before the ;; startup function runs, and mutated by every run. Its contents have to ;; survive a re-run for the same reason [counter]'s value does, and its root ;; has to survive collection either way. (defn table [] dyn {:runs 0}) (defvar state dyn (table)) (defn main [] i32 (agent/start "/tmp/flan-dev-rerun-fallback.sock") (set counter (+ counter 1)) (set zeroed (+ zeroed 2)) (put state :runs (+ (get state :runs) 1)) (print "counter ") (print counter) (println "") (print "zeroed ") (print zeroed) (println "") (print "runs ") (print (get state :runs)) (println "") (print "base ") (print base) (println "") ;; Long enough for a client to be served, short enough to park well inside ;; any watchdog — dev-macro.flan's clock, for its reason. (dotimes [i 200] (agent/wait 5)) 0)