;; lib/flow/tests/distributed.sx — Phase 4: distributed nodes via fed-sx (mocked). (define flow-dist-pass 0) (define flow-dist-fail 0) (define flow-dist-fails (list)) (define flow-dist-test (fn (name actual expected) (if (= actual expected) (set! flow-dist-pass (+ flow-dist-pass 1)) (begin (set! flow-dist-fail (+ flow-dist-fail 1)) (append! flow-dist-fails {:name name :expected expected :actual actual}))))) (define flow-d (fn (src) (flow-run src))) ;; A mock peer "edge" exposing double/inc, registered at the top of each program. (define peer-setup "(flow-peer-register! (quote edge) (list (list (quote double) (lambda (x) (* x 2))) (list (quote inc) (lambda (x) (+ x 1)))))") ;; ── remote-node ───────────────────────────────────────────────── (flow-dist-test "remote: a node executes on a peer" (flow-d "(flow-peer-register! (quote edge) (list (list (quote double) (lambda (x) (* x 2))))) (flow/start (remote-node (quote edge) (quote double)) 21)") 42) (flow-dist-test "remote: remote nodes compose in a sequence" (flow-d "(flow-peer-register! (quote edge) (list (list (quote inc) (lambda (x) (+ x 1))) (list (quote double) (lambda (x) (* x 2))))) (flow/start (sequence (remote-node (quote edge) (quote inc)) (remote-node (quote edge) (quote double))) 4)") 10) (flow-dist-test "remote: a remote node mixes with local nodes" (flow-d "(flow-peer-register! (quote edge) (list (list (quote double) (lambda (x) (* x 2))))) (flow/start (sequence (lambda (x) (+ x 5)) (remote-node (quote edge) (quote double)) (lambda (x) (- x 1))) 10)") 29) (flow-dist-test "remote: unreachable peer raises flow-remote-unreachable" (flow-d "(flow/start (try-catch (remote-node (quote ghost) (quote double)) (lambda (e) e)) 1)") "flow-remote-unreachable") (flow-dist-test "remote: unknown function on a peer raises flow-remote-no-fn" (flow-d "(flow-peer-register! (quote edge) (list (list (quote double) (lambda (x) (* x 2))))) (flow/start (try-catch (remote-node (quote edge) (quote missing)) (lambda (e) e)) 1)") "flow-remote-no-fn") (flow-dist-test "remote: a remote node can suspend the flow (peer returns control)" (flow-d "(flow-peer-register! (quote edge) (list (list (quote review) (lambda (x) x)))) (flow/start (sequence (remote-node (quote edge) (quote review)) (lambda (x) (suspend (quote human))) (lambda (v) (list (quote published) v))) 7)") (list "flow-suspended" 1 "human")) (flow-dist-test "remote: a transient remote failure is recoverable with retry" (flow-d "(define hits 0) (flow-peer-register! (quote edge) (list (list (quote flaky) (lambda (x) (begin (set! hits (+ hits 1)) (if (< hits 2) (raise (quote down)) (* x 3))))))) (list (flow/start (retry 3 (remote-node (quote edge) (quote flaky))) 7) hits)") (list 21 2)) (define flow-dist-tests-run! (fn () {:total (+ flow-dist-pass flow-dist-fail) :passed flow-dist-pass :failed flow-dist-fail :fails flow-dist-fails}))