qqeasonchen opened a new pull request, #5308:
URL: https://github.com/apache/eventmesh/pull/5308

   ### Motivation
   
   Fixes #5293
   Fixes #5288
   
   The uni-architecture cluster delivery currently mixes two modes: sticky 
delivery with cross-instance HTTP forwarding (`HttpForwarder` + 
`/internal/forward` endpoints) and partition assignment without fencing. The 
forwarding path adds an extra network hop, hidden failure modes, and makes 
delivery depend on instance-to-instance reachability. At the same time, 
partition assignment uses read-then-write generation overwrite, which is racy: 
a stale instance can silently overwrite the assignment of the rightful owner 
after a restart or a long GC pause. Finally, `ClusterMembership.heartbeat()` is 
never scheduled (#5288), so partition leases expire for live instances.
   
   ### Modifications
   
   **1. Sticky-only delivery topology (issue #5293)**
   
   - Delete `HttpForwarder` and the `/internal/forward` + 
`/internal/reply-forward` endpoints in `UniHttpServer`; `reply()` on a 
non-owner instance now 404s. The SDK pins to one instance via `instanceUrl`, so 
forwarding is no longer needed.
   - Remove `DistributionMode.LOAD_BALANCE_STICKY`; `LOAD_BALANCE` absorbs the 
sticky semantics (partition-key hash routes to one subscriber).
   
   **2. Atomic Meta CAS fencing (issue #5293)**
   
   - `MetaStore.tryAcquire(key, expectedOldValue, newValue)`: atomic 
compare-and-swap. InMemory: `ConcurrentHashMap` putIfAbsent/replace; Nacos 2.x: 
`publishConfigCas` with `casMd5 = MD5(expected content)`.
   - `FencingToken "<bootEpoch>:<counter>"` per JVM — monotonic and 
restart-safe. Assignment record `/em/assignments/<topic#partition>` = 
`"<token>|<ownerInstanceId>"`.
   - `acquireOrFence` three-branch protocol:
     - Case 1: unclaimed (or released tombstone `""`) → CAS claim
     - Case 2: still ours → sync token
     - Case 3: another owner → CAS takeover only when the owner is TTL-evicted 
or our token is strictly higher; otherwise we are fenced
   - `releaseStale`: partitions that left our assigner share are CAS'd to a 
`""` tombstone so the new rightful owner can claim them on its next cycle 
(prevents stranding after membership churn). The tombstone is CAS-equivalent to 
an absent key on both MetaStore backends.
   
   **3. Heartbeat scheduling fix (issue #5288)**
   
   - `ClusterMembership.heartbeat()` was never scheduled; `enableCluster` now 
runs it every 5s and releases it on shutdown together with the partition lease.
   
   ### Tests
   
   - `FencingTokenTest`, `InMemoryMetaStoreTest` (incl. concurrent CAS), 
`PartitionFencingTest` (first claim / race / restart fencing / stale CAS).
   - `ClusterDeliveryFaultTest`: in-process 3-4 instance fault injection 
(steady-state split, crash takeover, scale-out churn, Meta partition 
split-brain guard, healed partition reclaim) driven by a mutable clock — no 
sleeps, fully deterministic.
   - Removed `ClusterForwardIntegrationTest` / 
`NacosClusterForwardIntegrationTest` (they covered the deleted forwarding path).
   - Full runtime module suite green (189 tests, 0 failures); checkstyle clean.
   
   ### Documentation
   
   - Does this pull request introduce a new feature? (yes)
   - If yes, how is the feature documented? 
(`docs/eventmesh-uni-architecture-redesign.md` §13.2.10 updated with the 
acquireOrFence protocol, release path, and fault-injection test coverage)
   


-- 
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]

Reply via email to