qqeasonchen opened a new pull request, #5383: URL: https://github.com/apache/eventmesh/pull/5383
## What this PR does Three coupled review findings on the default cluster bootstrap — fixed together because they compose into one wiring path. **Closes #5376 · Closes #5377 · Closes #5378** ### #5376 — cluster-wide subscription routing for PARTITION_OWNED_PULL | Change | Effect | |---|---| | `enableCluster()` builds `ClusterSubscriptionStore` (Meta prefix watch) + `ClusterCoordinator` and injects via `withCluster()` | The partition owner's poll loop sees subscribers on OTHER instances (it dispatched through its LOCAL `SubscriptionManager` only → remote subscribers starved) | | New **`HttpForwarder`** | `POST /internal/forward` to the target instance (address via `ClusterMembership.addressOf`, bearer from `eventmesh.admin.token`, frame base64-wrapped) | | New **`POST /internal/forward`** on `UniHttpServer` | Decodes and delivers through the local reliable path — ACK/redelivery semantics identical for forwarded and local deliveries; 401 when the internal token is configured and missing | | `ClusterSubscriptionStore` put/remove now **apply locally BEFORE the Meta write** | A trailing own-apply escaped the authoritative Meta event order and could resurrect a concurrently-deleted value in the local cache (divergent views). The storm convergence test is now poll-stable. | ### #5377 — one PartitionOwnership lifecycle per instance `UniRuntime.startPartitionOwnership()` **reuses** the ownership that `enableCluster()` already built and installed into the ingress (one membership, one heartbeat loop, one fencing token); it self-constructs only when nobody wired one (embedder path). Previously the #5359 topology flip made `UniRuntime.start()` create a **second** `ClusterMembership` + `PartitionOwnership` with a different token and replace the ingress view — two divergent state machines per runtime. ### #5378 — durable delivery + DLQ ledger in the default bootstrap - `ReliableDispatcher.withStateStore()` / `withDeadLetterStore()`: post-construction injection for boot wiring order; the swap **fails closed** when deliveries are in flight. - `EventMeshApplication.main()` constructs `RocksDBDeliveryStateStore` under `<dataDir>/delivery-state` and (clustered) a `MetaBackedDeadLetterStore`, injects both, **logs the effective implementations at boot**, and closes the store on shutdown so in-flight records survive for restart recovery. The default path previously fell back to `InMemoryDeliveryStateStore` — a crash lost every pulled-but-unACKed delivery. ### Tests (new `ClusterBootstrapCompositionTest`, 4 cases) - `runtimeReusesPreInstalledOwnership` (#5377) - `coordinatorRoutesRemoteSubscriber` (#5376 — remote subscriber via forward, exactly one forward) - `durableStoresInjectIntoDispatcher` (#5378 — in-flight swap fails; post-clear swap + ledger attach take effect) - `rocksDbDeliveryStateStoreRoundTrips` (#5378 durability baseline) Local verification (Temurin 21.0.11): runtime tests + checkstyle (maxWarnings=0) + architecture-guard tests all green. Co-authored-by: qqeasonchen <[email protected]> -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
