Deltic leg: the conformance suite runtime-linked on stock Deno - #149
Merged
Conversation
…tock Deno The polymorph-webrtc-datachannels entry in the jco-replacement migration (lann/deltic#14), following the pattern polymorph-websocket#40 and polymorph-tls#36 established — side by side with the existing targets, nothing jco-side changes. - deltic-impl/: the deltic-native host module — jco-impl/webrtc.js ported to deltic's embedder conventions (WitError throws, typed streams), upstreamed from deltic's ports/webrtc reference where the echo-demo already ran over real data channels. node-datachannel-backed under stock Deno; unit tests included. - conformance/driver-ct/deltic/: the leg — run.ts mirrors the jco child contract exactly (RTC_CT_* env, --select prefix, results JSONL on stdout, the 512 KiB inbound bound via WEBRTC_MAX_INBOUND_BUFFER_BYTES); signaling.ts is the fetch mailbox ported from jco/signaling.js. - rtc-ct-driver: a Deno peer kind (loopback --kind deltic-deno) spawning the child with the leg's own deno.json/deno.lock (--frozen). - Pinning: deltic release pre-10cc776 — raw.githubusercontent import maps + committed deno.locks for the module graph, sha256-pinned translator-shim release asset (fetch-translator.ts, cached under target/deltic/), pin consistency cross-checked at run time. - Found while porting: PeerConnection.close() closed only the native channels, so a post-close send could still see readyState "open" under node-datachannel's asynchronous transition (solo/post-close-send was flaky under the callback ABI's faster await cadence). close() now latches the DataChannel wrappers (the WIT contract's "observed locally at once"); regression test added. Matrix: 5 loopback targets, 37/37 each; interop matrix unchanged. CI gains a pinned denoland/setup-deno step in the conformance matrix job; deltic-check (type-check + unit tests) rides the same job.
…anup Root-caused from this PR's first Conformance run (the deltic-check failures) with a probe matrix on the runner (branch deltic-ice-debug, run 31349796767; relates to lann/deltic#21): - connectPair() started its candidate pumps before the offer/answer exchange and swallowed addIceCandidate rejections. On a slow runner, libdatachannel delivers the host candidates ~12 ms in — before the counterpart has its remote description — so every candidate was rejected (invalid-signaling) and lost (the stream delivers each candidate once), and wait-connected timed out at 20 s. The dev box simply won the race. Runtime-independent: a raw-API probe replicating the racy ordering fails identically under Node. The pumps now hold each candidate until the receiving peer has its remote description; on the runner the fixed tests pair in ~1 s. - After every test passed, the process could still die 139 in native teardown: under deno test the runtime lives on past cleanup(), and the exit raced libdatachannel's thread joins (a hard exit right after cleanup() is clean — the standalone probes exit 0). The cleanup test now waits 1 s after cleanup() before the runner tears the isolate down. Runner-validated: deno task test exits 0 on ubuntu-latest.
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.
The polymorph-webrtc-datachannels entry in the jco-replacement migration (lann/deltic#14, scoped by lann/deltic#19 to the loopback matrix), following the pattern polymorph-websocket#40 and polymorph-tls#36 established — side by side with the existing targets, nothing jco-side changes.
What: a fifth loopback target
deltic-deno— the same bare suite the jco leg transpiles, runtime-linked under deltic on stock Deno: no transpile step, no generated tree, no--experimental-wasm-jspi; async exports run on the callback ABI.deltic-impl/— the deltic-native host module:jco-impl/webrtc.jsported to deltic's embedder API (typed streams,WitError), upstreamed from deltic'sports/webrtcreference where the echo-demo already ran over real data channels. node-datachannel-backed (same addon + version as the jco legs);useWerift()keeps the pure-TS fallback available. Unit tests included.conformance/driver-ct/deltic/run.ts— the child: mirrorsjco/run.mjsexactly (RTC_CT_*env,--selectprefix, results JSONL on stdout, the 512 KiB inbound bound exported viaWEBRTC_MAX_INBOUND_BUFFER_BYTES);signaling.tsis the fetch mailbox ported fromjco/signaling.js.rtc-ct-driver— aDenopeer kind (loopback --kind deltic-deno): spawnsdeno run --allow-all --frozen --config <leg>/deno.jsonwith the same child contract; solo stream + role-paired fold unchanged.Found while porting (the high-yield-defect-discovery argument for consumer-suite runs):
PeerConnection.close()closed only the native channels, so a post-closesendcould still seereadyState === "open"under node-datachannel's asynchronous transition —solo/post-close-sendwas flaky under the callback ABI's faster await cadence (the case's 1000-send bound raced the 1 s close-drain window).close()now latches theDataChannelwrappers, per the WIT contract's "observed locally at once"; regression test added. The same latent race exists injco-impl/webrtc.js(same drain, same addon — JSPI's slower awaits hide it); left untouched here for scope, happy to file separately.Pinning: deltic release
pre-10cc776in two import maps (conformance/driver-ct/deltic/deno.json+deltic-impl/deno.json; integrity via committeddeno.locks, enforced--frozen) andfetch-translator.ts(TAG + sha256 for the translator-shim release asset, cached undertarget/deltic/) — cross-checked at run time, incl. the module-identity constraint on the shared@deltic/runtime/embedderURL. Bump procedure inconformance/driver-ct/deltic/README.md.Gates run locally (linux-arm64 dev box):
just conformance— 5 loopback targets 37/37 each, all 13 interop directions, both aggregates, matrix-check against the regenerated committedmatrix.md(interop matrix unchanged);just gha::rust-checks;just deltic-check(type-checks + the 10 unit tests, clean exit — the leg and the impl map barenode-datachannelso itscleanup()resolves and the addon's native workers release before exit).CI: the conformance matrix job gains a pinned
denoland/setup-denostep;deltic-checkandconformance::run-delticjoingha::conformance-matrix. Note lann/deltic#21: deltic's own repo saw Deno×runner ICE timeouts for exactly this workload class while this repo's jco legs run green on the same image — this PR's Conformance run is the controlled A/B (same suite, same addon, Node vs Deno). If the deltic rows time out on the runner, that's the #21 delta isolated to the runtime, and I'll follow up here rather than absorb a red lane.