kj-rs-io: KJ async I/O interfaces backed by tokio - #7013
Conversation
|
APIError: Invalid Anthropic API Key |
2 similar comments
|
APIError: Invalid Anthropic API Key |
|
APIError: Invalid Anthropic API Key |
|
@danlapid Bonk workflow failed. Check the logs for details. View workflow run · To retry, trigger Bonk again. |
f0e4e76 to
d47bf26
Compare
d47bf26 to
8a0977b
Compare
Merging this PR will degrade performance by 8.84%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes
|
Third piece of the Rust I/O backend split (on top of kj-rs-tokio): implements KJ's async I/O surface over tokio sockets, driven by a KJ event loop on a TokioEventPort. - kj::AsyncIoStream over tokio TCP/Unix streams (readiness-based, cancel- safe: dropping a pending promise releases the interest), listeners with restrictPeers() enforcement and KJ-parity accept semantics (TCP_NODELAY, peer-address race tolerance), acceptAuthenticated() with KJ-identical NetworkPeerIdentity/LocalPeerIdentity, kj::Network / address parsing following KJ's grammar, and the low-level fd-wrapping providers. - kj_rs_io::setupTokioAsyncIo(): the drop-in kj::setupAsyncIo() replacement (event loop + providers + network), used by the final piece to swap workerd's I/O backend. - Signal watching (tokio's process-global signal registry routed through a runtime task so its cross-thread broadcast never touches the bridge's loop-thread-only wakers), an inotify/kqueue file watcher over AsyncFd, PeerFilter (a faithful port of kj::_::NetworkFilter, which lives in a KJ-internal header), the stream unwrap fast path for recovering native tokio sockets, and serve_kj_stream() for Rust servers consuming KJ streams. - Extensive C++-driven tests: stream contract, transfers, cancellation, DNS/connect ordering, refused connects (instrumented for a Windows CI wedge), unix sockets, peer identity, file watching, HTTP and Cap'n Proto RPC over the tokio backend. Adds bytes and socket2 to the workspace, plus tokio's io-util, macros, and signal features. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8a0977b to
6d084fb
Compare
jasnell
left a comment
There was a problem hiding this comment.
Largely agent driven review didn't reveal anything problematic. One style nit. Otherwise lgtm.
| if (!allowed) return false; | ||
| for (auto &cidr: denyCidrs) { | ||
| if (cidr.matches(addr)) { | ||
| if (cidr.getSpecificity() >= allowSpecificity) return false; |
There was a problem hiding this comment.
Nit... Combine these two ifs
Groundwork for the tokio-backed Rust I/O backend (kj-rs-tokio / kj-rs-io,
landing separately); kj-rs itself stays a pure Promise<->Future bridge.
cell (non-atomic kj::Refcounted; the bridge's single-thread axiom) that
arms the owning FuturePollEvent directly via Event::armDepthFirst(). The
cell's link to the event is weak and structurally invalidated when the
event dies, so wakers Rust retains past the future's lifetime (e.g.
parked in a channel's AtomicWaker) neutralize into safe no-ops instead of
arming a freed event. Waker ownership round-trips through RawWaker data
slots via kj::Rc::disown()/reown() -- hence the capnp-cpp pin bump to the
current v2 head, which carries those (merged upstream).
intrusive weak link (RustPromiseAwaiter::link / FuturePollEvent::leaves).
to its first suspension point at conversion, so KJ callers no longer need
a manual .eagerlyEvaluate(nullptr); RustFuture::lazily() is the escape
hatch for the rare cold case.
rejected promise) instead of aborting the process, mirroring the sync
bridge's catch_unwind path.
drives tokio tasks inside its own wait() (the upcoming kj-rs-tokio) can
nudge itself out of a blocking park; null/no-op by default.
unsafe into named FFI islands: deny(unsafe_code) crate-wide, re-allowed
per-module only where the FFI seam genuinely needs it.
umbrella, keeping kj-rs (and everything built on it) off the concrete kj
OS event loop.
FuturePollEvent shared-event semantics (shared-event-test), and expanded
future/awaiter coverage.