Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
ddbaf58
refactor(rust sdk): part 1
daflyinbed Jul 2, 2026
28c0834
fix(rust sdk): align grpc codec/consumer with server key spellings an…
daflyinbed Jul 2, 2026
f42aa95
feat(rust sdk): add self-contained e2e test suite with bundled docker…
daflyinbed Jul 2, 2026
c6e8c71
fix(rust sdk): make rocketmq compose profile boot on selinux/low-mem …
daflyinbed Jul 2, 2026
cae525f
test(rust sdk): switch e2e suite to the rocketmq compose profile
daflyinbed Jul 2, 2026
afe79ff
fix(rust sdk): create e2e topics as form-encoded, not JSON
daflyinbed Jul 2, 2026
ade2a90
fix(rust sdk): use per-call gRPC timeouts, not a channel-wide cap
daflyinbed Jul 2, 2026
e4be10a
fix(rust sdk): relocate rocketmq jars so the storage plugin's shadow …
daflyinbed Jul 3, 2026
bfb95c7
fix(rust sdk): make request/reply replies correlate with the original…
daflyinbed Jul 3, 2026
b01425f
fix(rust sdk): add graceful shutdown and axum-style stream driver
daflyinbed Jul 3, 2026
5ae3f42
Merge pull request #2 from daflyinbed/feature/rust-sdk-http
daflyinbed Jul 4, 2026
e1a01bd
feat(rust-sdk): tcp (#3)
daflyinbed Jul 6, 2026
421cb05
feat(rust-sdk): TCP auto-reconnect and CloudEvents support
daflyinbed Jul 7, 2026
1d213cc
fix(rust sdk): route one-way publish to publishOneWay RPC and check s…
daflyinbed Jul 7, 2026
95517c9
chore: add asf license header and cleanup
Jul 8, 2026
c4eb1f3
refactor: more idiomatic
Jul 8, 2026
d05206e
refactor: interval
Jul 8, 2026
a0681d0
refactor(rust-sdk): redesign consumer API — separate RPC from connect…
Jul 8, 2026
8c18ecd
test(rust-sdk): use eventmesh:jdk11-test image and harden e2e suite
daflyinbed Jul 8, 2026
ae31aba
fix(rust-sdk): set datacontenttype=application/cloudevents+json for T…
daflyinbed Jul 9, 2026
55059a0
feat(rust-sdk): concurrent dispatch in gRPC stream receive loop
Jul 13, 2026
c908852
fix(rust-sdk): prevent silent hang of gRPC subscribe_stream on curren…
daflyinbed Jul 13, 2026
b0f4aa7
fix(rust-sdk): address all 8 release-blocking review findings
daflyinbed Jul 13, 2026
b5ebb6d
fix(rust-sdk): strict is_success, TCP CloudEvent validation, unsubscr…
daflyinbed Jul 15, 2026
3da38b4
fix(rust-sdk): prevent TCP ghost writes, slow-consumer drops, driver-…
daflyinbed Jul 15, 2026
cbb1e51
fix(rust-sdk): redact secrets in Debug, strict HTTP retCode, (topic,u…
daflyinbed Jul 15, 2026
b94bbce
fix(rust-sdk): bound gRPC resubscribe waits
daflyinbed Jul 15, 2026
223e3e9
feat(sdk-rust): add OpenMessaging and CloudEvents APIs
daflyinbed Jul 15, 2026
a1f632a
fix(rust-sdk): preserve request reply metadata
daflyinbed Jul 15, 2026
7c0fd6a
feat(rust): add catalog and workflow clients
daflyinbed Jul 15, 2026
cc62e54
refactor: rust
daflyinbed Jul 16, 2026
60d3037
refactor: remove v2
daflyinbed Jul 16, 2026
fbbcadd
Refactor Rust SDK transports to preserve message dialects
daflyinbed Jul 16, 2026
304576b
Strengthen Rust E2E publish assertions
daflyinbed Jul 16, 2026
2e90142
Add Java/Rust interop E2E test wiring
daflyinbed Jul 16, 2026
43d006c
Add gRPC webhook consumers and per-call request timeouts
daflyinbed Jul 16, 2026
21b8d43
Polish Rust SDK APIs and release checks
daflyinbed Jul 16, 2026
76bcf68
Fix request reply and TCP E2E readiness
daflyinbed Jul 16, 2026
3f614de
Refactor event mesh components
daflyinbed Jul 17, 2026
5006585
Expand Rust SDK integration coverage
daflyinbed Jul 17, 2026
63dbe86
Document Rust SDK API, features, and verification workflow
daflyinbed Jul 17, 2026
7aced7d
Make generated gRPC modules crate-private
daflyinbed Jul 22, 2026
009da87
update
daflyinbed Jul 22, 2026
62b28f6
Remove obsolete files and code
daflyinbed Jul 23, 2026
e6b3708
fix(rust-sdk): align runtime compatibility coverage
daflyinbed Jul 28, 2026
8c1a974
Refine request-reply transport support and webhook protocol detection
daflyinbed Jul 28, 2026
9fa06ef
Refine event mesh application workflows
daflyinbed Jul 28, 2026
e5e7bef
Make Rust SDK transport dependencies feature-specific
daflyinbed Jul 29, 2026
047f515
Expand Rust SDK cross-SDK interoperability tests
daflyinbed Aug 5, 2026
34c1532
Normalize Apache license headers in Rust SDK interop files
daflyinbed Aug 5, 2026
ece325d
fix(rust-sdk): harden reconnects and CloudEvent conversion
daflyinbed Aug 9, 2026
7a90be8
docs(rust-sdk): consolidate project guidance
daflyinbed Aug 10, 2026
933f604
refactor: remove grpc legacy config
daflyinbed Aug 13, 2026
c53da14
refactor(rust-sdk): make gRPC channel explicit
daflyinbed Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ eventmesh-sdks/eventmesh-sdk-rust/
eventmesh-sdks/eventmesh-sdk-go/
eventmesh-sdks/eventmesh-sdk-c/

# Rust / Node build artifacts
**/target/
# Rust / Node build artifacts. Keep the pattern slashless so Docker excludes
# both the target directory itself and everything below it in any SDK context.
**/target
**/node_modules/

# IDE / editor cruft.
Expand Down
10 changes: 10 additions & 0 deletions eventmesh-sdks/eventmesh-sdk-rust/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Agent guidance for the EventMesh Rust SDK

This crate is independent of the repository's Gradle build. Before changing it, read the project-owned documentation instead of duplicating it here:

- [README.md](README.md) — supported features, installation, and public behavior.
- [CONTRIBUTING.md](CONTRIBUTING.md) — prerequisites, checks, end-to-end tests, documentation ownership, and code conventions.
- [ARCHITECTURE.md](ARCHITECTURE.md) — protocol boundaries, generated code, and transport-specific implementation constraints.
- [examples/README.md](examples/README.md) — runnable examples and exact feature flags.

Keep those files authoritative. Update this file only when instructions specific to coding agents cannot be expressed naturally in the contributor or architecture documentation.
48 changes: 48 additions & 0 deletions eventmesh-sdks/eventmesh-sdk-rust/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# EventMesh Rust SDK architecture

This document records implementation constraints and protocol boundaries. For public usage, see [README.md](README.md); for build and test commands, see [CONTRIBUTING.md](CONTRIBUTING.md).

## Public API boundaries

- `src/lib.rs` denies unsafe code.
- `src/transport/mod.rs` defines `Publisher` with async functions in the trait. It is not object-safe; use `GrpcProducer`, `HttpProducer`, or `TcpProducer` directly rather than `dyn Publisher`.
- Subscription is intentionally transport-specific. Each consumer owns its receive loop where applicable and exposes lifecycle methods suited to its protocol.
- `src/common/` contains protocol keys, status codes, constants, and the shared `LoadBalanceSelector`.

## Generated protobuf code

`build.rs` uses `tonic-build` to compile `proto/eventmesh-{service,cloudevents}.proto` into Cargo's `OUT_DIR`. It creates client stubs only and enables `--experimental_allow_proto3_optional`. The two `.proto` inputs and the hand-written `src/proto_gen.rs` wrapper are checked in. The generated Rust files remain in `OUT_DIR` and are loaded by `tonic::include_proto!`; under the current build setup, those generated files are not checked in. Add convenience aliases to `proto_gen.rs` rather than editing build output.

## Wire formats

`EventMeshMessage` is a business model, not a shared wire DTO. Each transport owns its serialization:

| Transport | Boundary | Encoding |
| --- | --- | --- |
| gRPC | `src/transport/grpc/codec.rs` | CloudEvents protobuf |
| HTTP | `src/transport/http/codec.rs` | Form URL encoding, with JSON in `content` |
| TCP | `src/transport/tcp/message.rs` | Length-prefixed binary frames with `EventMesh` magic |

TCP CloudEvents use `protocoltype=cloudevents` and raw `application/cloudevents+json` bytes, matching the Java runtime codec path.

## Configuration

- gRPC transport code consumes `GrpcConfig` and the matching producer or
consumer role options directly; it has no transport-private configuration
adapter.
- `GrpcChannel::connect` creates the tonic channel on the current Tokio
runtime. Roles receive the channel explicitly and clones share its
multiplexed HTTP/2 connection. Applications using multiple Tokio runtimes
create a separate channel in each runtime.
- `src/config/http.rs` defines `HttpClientConfig` and its builder. Server lists accept comma- or semicolon-separated `host:port[:weight]` entries and use the shared load balancer.
- `src/config/tcp.rs` defines `TcpClientConfig`, `ReconnectConfig`, and their builders. TCP keeps connect, protocol-control, business request, heartbeat, and reconnect timeouts separate for Java compatibility. Heartbeats and GOODBYE are fire-and-forget.

## HTTP lifecycle and routing

The managed `HttpConsumer` binds its axum callback server before registration, then owns registration, heartbeat, and shutdown. Applications that host their own endpoint use `WebhookRegistration` and the public codec helpers `parse_push_body`, `PushMessageRequestBody::to_event_mesh_message`, and `WebhookReply`. `WebhookHandler` and `WebhookState` in `src/transport/http/webhook.rs` are internal implementation details.

All SDK HTTP operations use code-header routing at `/`. The bodies are `application/x-www-form-urlencoded`, so sending them to a Runtime path-based handler can select an incompatible JSON model. The heartbeat runs every 30 seconds in a background Tokio task tied to a `CancellationToken`.

## TCP connection lifecycle

In `src/transport/tcp/connection.rs`, `establish()` performs the socket and HELLO handshake. `run()` wraps `io_loop()` in the reconnect loop. With reconnect enabled, I/O failures trigger exponential backoff and re-establishment. `take_reconnect_rx()` notifies consumers after successful reconnects so they can replay subscriptions.
72 changes: 72 additions & 0 deletions eventmesh-sdks/eventmesh-sdk-rust/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Contributing to the EventMesh Rust SDK

This guide covers `eventmesh-sdks/eventmesh-sdk-rust`. Repository-wide Apache EventMesh contribution requirements still apply.

## Prerequisites

- Rust 1.86.0 or newer (the crate MSRV)
- `protoc` on `PATH` for builds that enable `grpc`, `full`, or `e2e`
- Docker and a compatible EventMesh runtime only for live end-to-end tests
- Java 8 or newer and Maven for the optional cross-SDK interop tests

`build.rs` invokes `tonic-build`; generated protobuf code lives in `OUT_DIR` and must not be edited or committed.

## Local checks

Run these before submitting a Rust SDK change:

```bash
cargo fmt --check
cargo clippy --no-default-features --lib -- -D warnings
cargo clippy --features full --all-targets -- -D warnings
cargo test --features full
cargo doc --features full --no-deps
```

Use `cargo test --features full --test codec_test` for the codec test binary. Examples are feature-gated in `Cargo.toml`; compile the one you changed with its documented `cargo run --example ... --features ...` command, or compile all supported paths with `cargo check --examples --features full`.

## End-to-end tests

The e2e suite is opt-in so a normal `cargo test` never requires Docker:

```bash
cargo test --features e2e
```

The harness starts the `rocketmq` docker-compose profile unless `EVENTMESH_E2E_EXTERNAL=1` points it at an already running runtime. An absent runtime is a failure by default. `EVENTMESH_E2E_ALLOW_SKIP=1` is only for an intentional local skip and must not be used for release verification.

The bundled compose file pins the Runtime to `apache/eventmesh:v1.12.0`. Run the bidirectional Rust/Java gRPC, HTTP, and TCP checks with:

```bash
cargo test --features interop_e2e --test e2e interop
```

Those tests build `interop/java-peer` with Maven on first use. The standalone peer depends on `org.apache.eventmesh:eventmesh-sdk-java:1.12.0-release`; it does not compile or load the Java SDK source tree from this repository.

The TCP reconnect test runs in the normal e2e suite. It uses a unique client subsystem and the Runtime admin API to disconnect only its own TCP sessions, so it does not restart or disrupt the shared Runtime container.

Each test uses a unique topic and consumer group. gRPC and HTTP cases may run in parallel; TCP cases are serialized because Runtime route refresh and RocketMQ rebalance state are shared. The harness creates and warms topics through the admin API before publishing.

The standalone in-memory broker requires a topic and subscription before the first publish and does not implement request/reply. Use a runtime profile with request/reply support for complete release verification. Topic creation uses form URL encoding at `POST /topic`.

## Documentation responsibilities

Keep each document in its intended layer.

| Change | Update |
| --- | --- |
| Installation, feature choice, or common behavior | `README.md` |
| Public type, method, feature-gated API, or behavior | rustdoc in `src/` |
| Runnable workflow or transport use | the matching file in `examples/` and `examples/README.md` |
| Validation, e2e, or contributor workflow | this file |
| Protocol boundary or internal architecture | `ARCHITECTURE.md` |

Public rustdoc should state feature requirements, ownership/lifecycle rules, and error or acknowledgement behavior where relevant. Prefer an executable doctest when it has no runtime dependency; otherwise mark the snippet `rust,ignore` and point users to a runnable example.

## Code conventions

- Add the Apache license header to every new `.rs` file.
- Mirror the established consuming builder style for configuration additions.
- Keep transport wire formats behind the public v2 API. Do not expose private legacy adapters merely to reuse an implementation detail.

Follow the additional protocol boundaries and internal constraints in [ARCHITECTURE.md](ARCHITECTURE.md).
Loading