appcore-peer-rpc
Crate-owned guide and examples
The Runtime repository maintains the detailed guide, basic example, and intermediate example. The wiki summarizes the public boundary; API and executable details live beside the crate code.
Responsibility: authenticated direct peer client, HTTP host, validation and replay protection.
Internal dependencies: core, distributed contracts, security and transport.
Primary API: token issuer/authenticator/dispatcher traits and HashToken or static implementations; in-memory/file nonce stores; validation config, validator and signing/payload hashes; retry/client config and transport trait; pooled and standard one-shot transports; HTTP state and host.
Use PooledPeerRpcTransport to reuse bounded per-origin connections.
StdPeerRpcTransport preserves the V1 one-shot Connection: close behavior.
Both consume the owned HTTP DTO body allocation. Uncompressed V1 and exact V2
bodies retain the same Vec<u8> through HttpRequest, without a complete clone
at the transport boundary.
The V1 client moves an owned outbound payload into one envelope retained across bounded retries. Each retry still refreshes temporal fields, nonce, token binding, and HTTP encoding. With a 4 MiB payload across five Apple M1 release processes, p50 stayed within +0.08%, peak RSS fell 7.21%, workload RSS delta fell 9.02%, and retained RSS delta fell 7.99%.
On ingress, decode_peer_rpc_envelope_json enforces the encoded ceiling and
deserializes an uncompressed V1 body directly from borrowed HTTP bytes. The
Runtime then moves the decoded payload allocation into CommandEnvelope. A
five-process 4 MiB workload reduced p50 from 53.06 to 52.35 ms, peak RSS from
35.80 to 23.81 MiB and workload RSS delta by 39.52%.
Use it only after tenant, cluster, source, target, protocol, expiry, nonce and
payload integrity can be established. AllowPeerAuthenticator is for tests,
not remote production.
Peer request, response, outbound and HTTP DTO Debug output reports payload
lengths and omits opaque bytes, credentials, nonce/idempotency values and remote
error details.
The process-local BoundedReplayStore validates every nonce at 128 bytes,
bounds both live entries and estimated retained bytes, and never permits a
default ceiling above 32 MiB. Operators can select a tighter ceiling and read
current, peak, maximum and rejection counters without exposing nonce values.
Maturity: stable peer protocol V1 surface.
Bounded V2 codec
PeerRpcChunkEncoder and PeerRpcChunkAssembler process an explicitly selected
V2 stream one bounded chunk at a time. Defaults cap decoded chunks at 64 KiB,
encoded chunks at 96 KiB, the aggregate at 64 MiB and chunk count at 1,024.
Encoded bytes use a canonical base64 JSON string, never an integer array.
Sequence, exact decoded size, chunk and aggregate SHA-256, deadline,
cancellation and quota after gzip decompression fail closed. A failed commit
never exposes the partial sink as complete. Identity chunks move the same owned
allocation from source to frame to assembler instead of cloning decoded bytes
at either boundary. A fixed stack-only full-chunk probe suppresses speculative
gzip only when the chunk appears already incompressible; structured
compressible chunks still use gzip.
PeerRpcStreamRegistry owns partial sessions under exact session and decoded
byte quotas. It writes request chunks to exclusive files in an existing
owner-only spool directory, dispatches only verified commits and returns
responses through explicit bounded pull frames. Error, cancellation, expiry
and completion release the partial file and reservation. Snapshots expose
active sessions, reserved bytes, saturation and cleanup counters.
Unix validates the effective owner and 0700/0600 directory/file modes.
Windows rejects reparse points and every allow ACE outside the current process
owner SID. Unsupported platforms fail closed during registry construction.
Enable the signed HTTP routes only with
PeerRpcHttpHost::with_v2_stream_registry; the default host remains V1-only.
query_stream_v2 and command_stream_v2 bind each exact JSON body to a bearer
token and move request/response data one frame at a time. Canonical JSON is
serialized directly into SHA-256 for this binding, without retaining a second
complete encoded body beside the frame. Dependants can reuse the byte-exact
path through json_payload_hash. Open admission checks
tenant, cluster, target, trace, deadline, command idempotency and bounded nonce
replay. Ambiguous frames are not retried; best-effort cancellation is backed by
authoritative deadline cleanup.
JSON remains the V2 default. Binary framing requires
with_v2_binary_codec() on the host and
with_stream_codec_v2(PeerRpcStreamCodecV2::Binary) on the client. Separate
query/command paths require the exact Postcard media type and bind the token to
the exact binary body. Binary bodies never use HTTP gzip; decoded bounds,
optional chunk gzip and integrity hashes remain unchanged. Missing or
mismatched binary support is terminal and never falls back to JSON.
Typed V2 rejections
The appcore-peer-rpc 1.0.2-rc candidate consumes PeerRpcWireErrorV2 from the
explicit appcore-distributed-contracts 1.0.2-rc endpoints. Its code
fixes the phase and retryability; retry delay is bounded to
300 seconds, correlation to 128 bytes and the protocol-owned redacted message
to 256 bytes. The client rejects contradictory known metadata. Unknown codes
discard their remote message/hint and become one observable, terminal
unknown result.
Stable V1 responses keep their existing JSON shape. The client maps only exact
host codes to PeerRpcError::RemoteRejected; only exact endpoint/replay
capacity rejections enter the existing bounded retry loop. No substring or
free-form message controls retry. V2 frame acknowledgement ambiguity still
forbids automatic frame retry.
Update caller and target before selecting the V2 endpoint. Stable V1 remains supported for legacy deployments and is never upgraded, converted or disabled automatically.
Clean-source release certification at 6f3bc38 measured 25% fewer body bytes,
93% lower codec p99 and a 14% smaller bounded codec buffer for binary frames
from 64 KiB through 4 MiB. The 1 KiB case improved 38%/65%/18%; whole-suite
peak RSS was 306,448 KiB. /v1/peer/* parses only V1 and never infers V2. The
binary codec remains development-only until Linux/Windows evidence is attached.