Skip to content

Native frame model#357

Open
PLeVasseur wants to merge 9 commits into
eclipse-uprotocol:mainfrom
PLeVasseur:native-frame-model
Open

Native frame model#357
PLeVasseur wants to merge 9 commits into
eclipse-uprotocol:mainfrom
PLeVasseur:native-frame-model

Conversation

@PLeVasseur

Copy link
Copy Markdown
Contributor

So -- clearly this is a lot.

The work is broken down by commits to clarify what's being done and why.

Let's be honest! I don't know that all of this will be shipped as-is. Let's take it slow and look through it. I think the docs (see below) are a good starting point.

Docs

I've put the generated docs here on my blog temporarily:
https://petelevasseur.com/up-rust-preview/up_rust/index.html

I've spent some time over the last week or so trying to refine these to make them easier to get up to speed.
I think they can also be nice as a starting point for review.

up-spec changes

The relatively small number of changes to up-spec are in this PR to support full compatibility:
eclipse-uprotocol/up-spec#331

Testing

I've had this testing thoroughly on a large matrix of implementations of wires and transports.

The proposed native-frame-model stack has been validated across up-rust, its
wire adapters, six transport implementations, and Streamer. The central
integration check was an exhaustive 2,160-row directed compatibility matrix:

12 source profiles x 12 sink profiles x 3 communication roles x 5 encodings
= 2,160 scenarios

Wires and encodings

Every profile pairing and communication role was generated for five encoding
choices:

  • native uProtocol frame encoding;
  • protobuf;
  • XCDRv2;
  • Apache Arrow;
  • OMG IDL.

The three external wire implementations (XCDRv2, Arrow, and OMG IDL) also passed
their independent compatibility suites: 44/44 validation cards.

Transports and profiles

The matrix covers six real transport implementations through 12 endpoint
profiles:

  • DDS: classic, copy-minimized, and owned-frame;
  • Zenoh: classic, copy-minimized, and owned-frame;
  • Eclipse iceoryx2: copy-minimized and owned-frame;
  • S-CORE LoLa: copy-minimized and owned-frame;
  • MQTT 5: classic;
  • SOME/IP (vSomeIP): classic.

Every directed source-to-sink profile pairing was considered for
publish/subscribe, notifier/notifyee, and client/server RPC communication.

Results

Result Rows
Passed 1,728
Approved structural unsupported 432
Blocked 0
Failed 0
Total 2,160

The 432 unsupported rows are deliberate, mechanically classified cases: 180 identical-profile rows with no bridge boundary to exercise, and 252 Arrow/OMG IDL combinations not implemented by the classic MQTT5 or vSomeIP role binaries. Every supported combination passed. No row needed a retry.

The run also completed 7,110/7,110 process-group leak checks with zero leaks. All six transports passed their strict/native validation suites, and Streamer passed 16/16 graph, criteria, workspace, and benchmark cards.

The final documentation relayering changes only crate documentation; compiled source, manifests, tests, feature graph, and transport behavior are unchanged, so this functional matrix evidence applies directly to the reviewed stack.

Enforce missing_docs and missing_debug_implementations at deny in the
manifest, document every public item (including mockall-generated test
hooks and integration-test crate roots), and complete the Debug story
with finish_non_exhaustive impls where deriving would expose internals.

Adopt clippy-conformant accessor names (code, message, time, value,
type_url) with deprecated forwarding aliases for every renamed
upstream getter, so no caller breaks.

Introduce communication-api and up-core-api as the primary feature
names, with up-l2-api and up-core-types retained as forwarding
aliases: the old core-types name misdescribed its scope (the feature
gates the generated up_core_api module; the core message types are
unconditional).

Every commit in this series builds and tests green in isolation.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
Moves the up-spec submodule to the revision adding the three optional
open payload-encoding identity fields to UAttributes (companion
up-spec pull request: one commit, wire-compatible, enum untouched).
This series' frame model projects payload encodings through those
fields; nothing else in the spec pin changes.

The pin targets the companion PR's head and is retargeted to its
merged SHA before this series merges. The regenerated up_core_api
module gains the new optional fields; no existing field, message, or
service changes.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
Introduce the UFrame data model the up-spec revision defines: validated
UFrameMetadata with projections to and from UAttributes and UMessage
(method forms), the canonical field-block codec with golden coverage
and a generative round-trip property, the ABI layout contract, the
read-side UFrameView trait, and the payload codec vocabulary
(PayloadCodec, ReadDecodePayload, PayloadLayout, UWireError) the frame
families share.

UAttributes gains the three optional payload-encoding fields from the
spec revision; UMessageBuilder::build_with_payload_encoding and
UMessage::with_assumed_payload_encoding bridge the existing builder to
the encoding-aware world. Existing behavior is unchanged when the new
surface is unused.

Shims: get_validator/get_validator_for_attributes retained as
deprecated aliases of the clippy-conformant names.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
UOwnedFrame with a validation typestate (Unvalidated/Validated) so an
invalid frame cannot cross a transport boundary by construction, the
UOwnedTransport/UOwnedTransportImpl role split with filter validation
ahead of the implementation seam, UOwnedListener delivery, the frame
envelope for lossless carriage of native frames over ordinary byte
channels, the UFrameView implementation for owned frames, and an
in-memory reference transport behind test-util with lifecycle
coverage (matching filters delivered, non-matching filtered,
unknown unregistration is NotFound).

Feature owned-frame-transport, default-off.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
…ental]

Loan/lease transmit and receive model: UTxLoanSpec with the shared
validation typestate, loaned payload buffers including the
uninitialized-loan surface, UZeroCopyTransport role/impl split with
validation ahead of the seam, UZeroCopyListener delivery, typed payload
loans, and stable payloads (byte-backed container model) with their
proc-macro derives in the new up-rust-macros workspace crate. In-memory
reference transport behind test-util.

Features zero-copy-transport (default-off); cfg names owned by later
commits in this series (selected-wire adapter, perf diagnostics,
contract fixtures) appear in shared files ahead of their declaration
and are warn-only until their commit lands.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
…ntal]

The three-trait wire split: UWire (identity constants), the payload
codec traits, and UWirePayload (the per-payload codec binding) — kept
separate so one wire identity can bind different codecs per payload
type. bind_wire_self_codec! writes the common Codec-equals-marker
binding; a trait-level associated-type default is unstable Rust and a
blanket impl would forbid the two-codec case by coherence (both
rejections recorded in the macro docs with a compiled example).

Ships the registered identities (native, protobuf, stable-container,
XCDRv2 families), the native-prefix metadata codec, and wire
compatibility checks. Features wire-implementer-api and
selected-wire-user-api (the transport-adapter edge joins in the
selected-wire commit).

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
UWireTransport composes an encoded transport core with a statically
selected wire: metadata encode/decode with identity stamping and
verification ahead of the core seam, UWireRx typed receive leases with
in-place payload decode, and the encoded-frame adapter surface. The
transport-implementer-api feature gates the core-facing SPI; the
selected-wire user door re-exports only the user surface.

Completes the deferred feature edges: owned-frame-transport ->
selected-wire-transport-core and selected-wire-user-api ->
selected-wire-transport-adapter.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
…xperimental]

communication::owned mirrors the classic role set (Endpoint, Publisher,
Subscriber, Notifier, RpcClient, RpcServer) over an owned-frame
transport, with the spec-aligned service-first Subscriber contract.
communication::zero_copy carries the typed-init publish path and the
lease-preserving Subscriber that consults uSubscription before
registering and delivers UWireRx leases.

LocalTransport is re-exported at the crate root behind its util gate.

The guide lands as rendered rustdoc chapters (applications,
transports, wires, and the trait map): a learning path through the two
families, the two-path table (codec path: one serialization, zero
copies; stable path: zero serializations), and every role trait linked
to its home.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
Trybuild compile-fail pins (validation typestates cannot cross
transport boundaries; the user door does not expose implementer SPI;
wildcard URIs cannot pose as exact filters — ExactUUri now exported;
stable-payload layout rules; feature-surface pins), the wire metadata
conformance and exact-byte golden suites, the cross-family payload
tri-state contract suite with its external fixture crate, Miri
coverage for stable containers, Criterion benches with their fixture
module, and the CI workflow updates. Remaining fixture features
declared (payload-contract-*, perf-diagnostics, protobuf-wire);
docs.rs metadata configured for all-features rendering.

Signed-off-by: Pete LeVasseur <plevasseur@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant