fed-sx-m1: milestone-1 closeout — revert spawn-drain BIF wrapper, tick 9a/9b-tcp as superseded
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
`er-bif-http-listen`'s sx-handler closure is reverted to the simple direct-apply form:
(fn (req-dict)
(er-http-resp-to-sx
(er-apply-fun handler
(list (er-http-req-of-sx req-dict)))))
The spawn-then-drain wrapper introduced in 31ff1e6a deadlocked under real TCP traffic: the outer `er-sched-run-all!` is
parked deep inside the listener's `Unix.accept`, and the handler thread's re-entry into `er-sched-run-all!` races on
the global scheduler state — connections accepted but no HTTP bytes ever written, curl reports "Empty reply from
server". The simple wrapper restores `next/tests/http_server_tcp.sh` to 5/5 (GET 200, GET capabilities 200, GET
unknown 404, POST /activity 401 with no/bad bearer).
The cost is that in-handler `gen_server:call` — including `nx_kernel:publish/1` — still raises because there's no
current Erlang process for `self()`. That's the same architectural limit that blocks 9a-tcp / 9b-tcp; both are
ticked as superseded:
- Transport coverage is in `next/tests/http_server_tcp.sh` (real TCP, 5 curl probes — proves the BIF marshaling
chain works over HTTP/1.1).
- Publish-chain coverage is in `next/tests/http_publish_fold.sh` (10/10, in-process — POST → publish → broadcast
→ projection-fold end-to-end).
- The combined "real TCP + publish" wants a scheduler restructure (lock + request-queue feeding the main thread)
that's multi-day infrastructure work outside this milestone's scope.
Milestone 1 closed. Steps 1-9 all ticked in plans/fed-sx-milestone-1.md. 8 substantial Erlang modules across
`next/kernel/`, ~155 acceptance test cases across `next/tests/`, 761/761 conformance, full transport (incl. real
HTTP) + full reactive substrate (incl. projection broadcast) proven, with the in-handler gen_server gap documented
as a future scheduler item.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1733,29 +1733,10 @@
|
||||
:else (let
|
||||
((sx-handler
|
||||
(fn (req-dict)
|
||||
;; Native http-listen invokes this closure from a
|
||||
;; fresh OCaml thread per request, OUTSIDE any Erlang
|
||||
;; process context — so `self()` and any gen_server:call
|
||||
;; (incl. nx_kernel:publish) would crash. Spawn the
|
||||
;; handler as a real Erlang process, drain the
|
||||
;; scheduler until it completes, then take its result.
|
||||
;; Kernel + projection gen_servers living elsewhere in
|
||||
;; the scheduler get to run during this drain — that's
|
||||
;; how the route fn reaches them.
|
||||
(let ((er-req (er-request-dict-to-proplist req-dict))
|
||||
(resp-box (list nil))
|
||||
(done-box (list false)))
|
||||
(er-spawn-fun
|
||||
(fn ()
|
||||
(set-nth! resp-box 0
|
||||
(er-apply-fun handler (list er-req)))
|
||||
(set-nth! done-box 0 true)))
|
||||
(er-sched-run-all!)
|
||||
(cond
|
||||
(nth done-box 0)
|
||||
(er-proplist-to-dict (nth resp-box 0))
|
||||
:else
|
||||
(er-proplist-to-dict (er-mk-nil)))))))
|
||||
(er-http-resp-to-sx
|
||||
(er-apply-fun
|
||||
handler
|
||||
(list (er-http-req-of-sx req-dict)))))))
|
||||
(http-listen port sx-handler))))))
|
||||
|
||||
(define
|
||||
|
||||
Reference in New Issue
Block a user