feat(core): metaserver flush barrier + embeddable P2P transfer service#381
Merged
Conversation
Two additions for in-process Rust embedders (e.g. openinfer) that serve cross-node RDMA fetches without running the full pegaflow-server binary: - MetaServerClient::flush(): a barrier over the fire-and-forget registration queue. Resolves once every insert/remove enqueued before the call has been delivered to the MetaServer or dropped after a failed attempt. Exposed as PegaEngine::flush_saves_and_registrations() (write pipeline drain first, so block-seal registrations are enqueued before the barrier). This is the P/D handoff barrier: a prefill node flushes before signalling KV-ready, so a decode node's MetaServer query is guaranteed to observe the registrations. - P2pTransferService: the minimal Engine gRPC surface a serving peer must expose (RdmaHandshake / QueryBlocksForTransfer / ReleaseTransferLock + Health), with every IPC-registration RPC answered unimplemented. pegaflow-server keeps its full service; this is for embedders that drive PegaEngine in-process. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s, serve_with_incoming - Bump cudarc floor to 0.19.7 and adapt to its regenerated sys bindings: CUmemAllocationHandleType is now a newtype over c_uint, so the multicast handleTypes bitmask reads .0 instead of an enum cast, and cuda_sys.rs re-binds the handle-type constants as consts (associated constants cannot be `pub use`d). Lets embedders on cudarc 0.19.5+ keep per-symbol lazy loading instead of downgrading to 0.19.3. - P2pTransferService::serve_with_incoming: caller-bound listener variant so embedders can fail loud on a taken port before reporting ready. - flush_saves_and_registrations docs: the barrier bounds *when* delivery is attempted, never *whether* it succeeds — dropped registrations degrade to peer-side recompute, not an error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
RcBackend::new (the rdma transport bring-up) calls init_logging on first use. When pegaflow-core is embedded as a library the host process has long since installed its own logger, and logforth's apply() panics — taking down the host's engine loader thread. Use try_apply and log the skip to stderr: the host's logger receives our records; its existence is not an error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The router rewrites max_tokens=1 for the P node, but chat clients send the modern max_completion_tokens field (OpenAI deprecated max_tokens for chat). Engines prefer max_completion_tokens when both are present, so P ran the full decode: every turn paid prefill + complete generation on P before D even started, inflating multi-turn P/D TTFT from ~110ms to ~1.5s per turn (Qwen3-8B 1P+1D, 10-way concurrency, 4k prompt + 1k/turn). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 tasks
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feifei-111
approved these changes
Jul 3, 2026
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.
What
Three additions that let an in-process Rust embedder (e.g. openinfer) serve cross-node RDMA fetches without running the full pegaflow-server binary:
MetaServerClient::flush()— a barrier over the fire-and-forget registration queue. Resolves once every insert/remove enqueued before the call has been delivered to the MetaServer or dropped after a failed attempt. Exposed asPegaEngine::flush_saves_and_registrations()(write-pipeline drain first, so block-seal registrations are enqueued before the barrier runs). This is the P/D handoff barrier: a prefill node flushes before signalling KV-ready, so a decode node's MetaServer query observes every registration that made it through; dropped registrations degrade to decode-side recompute.P2pTransferService— the minimalEnginegRPC surface a serving peer must expose (RdmaHandshake/QueryBlocksForTransfer/ReleaseTransferLock+Health), with every CUDA-IPC registration RPC answeredunimplemented. pegaflow-server keeps its full service; this is for embedders that drivePegaEnginein-process. Includesserve_with_incomingso embedders can bind first and fail loud on a taken port.logging::initusestry_apply—RcBackend::newcallsinit_loggingon first use; when pegaflow-core is embedded as a library the host process has already installed its own logger, and logforth'sapply()panicked, taking down the host's engine loader thread. The host's logger receives our records; its existence is not an error.Also bumps the cudarc floor to 0.19.7 and adapts to its regenerated sys bindings (
CUmemAllocationHandleTypeis now a newtype overc_uint; the multicasthandleTypesbitmask reads.0instead of an enum cast, andcuda_sys.rsre-binds the handle-type constants asconsts since associated constants cannot bepub used).Tests
cargo test -p pegaflow-core --features rdma --lib internode: 7/7 pass.PegaEnginewith this branch; decode discovered the prefill node's KV via the MetaServer and pulled 33/33 blocks (74.2 MiB) over RDMA READ; greedy output token-identical to the single-instance baseline across block-boundary prompt lengths; killing the MetaServer or the prefill node degrades to local prefill with no crash or hang.🤖 Generated with Claude Code