ariadne: generic async URI resolver — (fetch uri) / (fetch-async uri) (§13.8) - #475
Merged
Merged
Conversation
… (§13.8)
Add a scheme-agnostic async resolver so an ari program can load ANY registered
URI scheme (file/state/cvc/http) without blocking the scheduler thread — the DSL
surface for "all ari-generated URI requests async".
net_intrinsics.cpp: launch_uri_fetch runs the SYNCHRONOUS cvc::ariadne::resolve()
on a compute-pool worker (OFF the scheduler thread) and posts the marshalled result
to a unique '#'-reply channel — the same launch shape as launch_http_fetch, but for
arbitrary URIs. Two verbs reuse the PR-A park/future machinery:
(fetch-async URI [BASE]) -> a future handle (await it, or msg-recv it)
(fetch URI [BASE]) -> TRANSPARENT: self-parks, returns the dict directly
The reply dict is { ok body(bytes) url error } (scheme-agnostic: no HTTP
status/headers). So (get-attr (fetch uri) "body") reads as one expression.
The register gate is split so (fetch*) does NOT require an HTTP backend — it works
over any registered scheme and is useful in a curl-less build — while (http-get*)
still gate on cvc::net::have_http_backend(). resolve() is app-free and has its own
try/catch barrier; the worker additionally wraps it and always posts a dict, so a
waiter never hangs.
The other ari-generated URI requests stay synchronous by design: import:/load:/
include: resolve at LOAD time (off the draw walk, where sync is legal), and scene
source:{uri:} is a one-shot at scene setup (not per-frame) — so nothing
ari-generated blocks the render thread today. A DSL program that wants async
loading uses (fetch). An async scene source:{uri:} realize (so a large remote asset
doesn't block scene setup) is a follow-up.
Tests (ariadne_runtime_test AriadneNetIntrinsics, offline): (fetch) transparently
resolves a canned custom scheme with the bytes body threaded in; (await
(fetch-async …)) resolves the future. Full ariadne_runtime_test 106, 0/20 flaky.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a scheme-agnostic async resolver so an ari program can load any registered URI scheme (
file/state/cvc/http) without blocking the scheduler thread — the DSL surface for "all ari-generated URI requests async". Builds on PR-A (#474)'s park/future machinery.What it does
launch_uri_fetchruns the synchronouscvc::ariadne::resolve()on a compute-pool worker (off the scheduler thread) and posts the marshalled result to a unique#-reply channel — the same launch shape aslaunch_http_fetch. Two verbs reuse PR-A's park/future primitives:(fetch-async URI [BASE])→ a future handle (await it, ormsg-recvit).(fetch URI [BASE])→ transparent: self-parks and returns the dict directly.Reply dict:
{ ok body(bytes) url error }(scheme-agnostic — no HTTP status/headers; usehttp-getfor those). The register gate is split so(fetch*)needs no HTTP backend (works over any registered scheme, even in a curl-less build) while(http-get*)still requirecvc::net::have_http_backend().resolve()is app-free with its own barrier; the worker wraps it and always posts a dict, so a waiter never hangs.Scoping (the honest answer to "all ari URI requests async")
The other ari-generated URI requests stay synchronous by design:
import:/load:/include:resolve at load time, off the draw walk (roadmap §13.8 — sync is legal there), and scenesource:{uri:}is a one-shot at scene setup (not per-frame). So nothing ari-generated blocks the render thread today; a DSL program that wants async loading uses(fetch). An async scenesource:{uri:}realize (so a large remote asset doesn't block scene setup) is a natural follow-up (it needs an asyncresolve_to_file+ temp-file lifetime across the hop).Tests
ariadne_runtime_test(AriadneNetIntrinsics, offline):(fetch)transparently resolves a canned custom scheme with the bytes body threaded in;(await (fetch-async …))resolves the future. Fullariadne_runtime_test106, 0/20 flaky.Next in the arc: render-pass park budget + safety (PR-C — residents currently run with no time budget).