zhaohai666 opened a new pull request, #10705:
URL: https://github.com/apache/rocketmq/pull/10705

   ## [Studio] feat: Route Change Event Detection and Notification System
   
   **Issue:** #10635
   **Branch:** `feature/rip-2-pr4-route-change-event`
   
   ---
   
   ### Overview
   
   This PR implements the route change event detection and real-time 
notification system for the RIP-2 Proxy Admin Interface. It monitors topic 
route data changes (broker online/offline, queue scaling, topic 
creation/deletion) and pushes events to subscribed gRPC clients via 
server-streaming RPCs.
   
   ### Key Changes
   
   **RouteChangeEventDetector** -- Core detection engine (357 lines) that 
compares old vs. new `TopicRouteData` to produce a list of `RouteChangeEvent` 
objects.
   
   - `detectChanges(topic, oldRoute, newRoute)`: Main entry point. Delegates to 
specialized detection methods and returns a consolidated event list.
   - `detectBrokerChanges()`: Compares `brokerDatas` maps (brokerName -> 
brokerId -> address). Emits `BROKER_ONLINE` / `BROKER_OFFLINE` for new/removed 
broker names, new/removed broker instances (brokerId), and address changes 
(treated as offline + online pair).
   - `detectQueueChanges()`: Compares `queueDatas` per brokerName. Emits 
`QUEUE_SCALE` when read or write queue counts differ.
   - `detectBrokerOnlineEvents()` / `detectBrokerOfflineEvents()`: 
Bulk-generate broker events for topic create/delete scenarios.
   - `buildSnapshot()`: Builds a `TopicRouteSnapshot` for initial state 
synchronization.
   
   **RouteChangeNotifier** -- Manages gRPC subscriber streams and broadcasts 
detected events (245 lines). Implements 
`TopicRouteService.RouteRefreshListener`.
   
   - `subscribe(topics, eventTypes, StreamObserver)`: Registers a subscriber 
with optional topic and event-type filters. Wires up `setOnCancelHandler` for 
client disconnect cleanup. Sends an initial `ROUTE_SNAPSHOT` for all cached 
topics upon subscription.
   - `onRouteRefreshed(topic, oldView, newView)`: Callback from 
`TopicRouteService` cache reload. Delegates to `RouteChangeEventDetector` then 
broadcasts matching events to all subscribers.
   - Uses `CopyOnWriteArrayList` for thread-safe subscriber management.
   - Inner class `RouteEventSubscription` holds topic filter (`Set<String>`), 
event-type filter (`Set<RouteChangeEventType>`), and the `StreamObserver` with 
`matches()` filter logic.
   
   **TopicRouteService Extensions**
   
   - Added `RouteRefreshListener` interface with `onRouteRefreshed(topic, 
oldView, newView)` method.
   - Modified the Caffeine cache `reload()` callback to notify all registered 
listeners after a successful route reload, passing both old and new 
`MessageQueueView`.
   - Added `addRouteRefreshListener()` for listener registration.
   - Added `getAllTopicNames()` and `getCachedTopicRouteData()` for accessing 
cached route state.
   
   **Data Models**
   
   | Model | Description |
   |-------|-------------|
   | `RouteChangeEvent` | Event payload: eventType, timestamp, topic, cluster, 
brokerName, brokerAddress, brokerId, previous/current read/write queue nums, 
routeSnapshot |
   | `RouteChangeEventType` | Enum with 6 values: `BROKER_ONLINE`, 
`BROKER_OFFLINE`, `QUEUE_SCALE`, `TOPIC_CREATE`, `TOPIC_DELETE`, 
`ROUTE_SNAPSHOT` |
   | `TopicRouteSnapshot` | Point-in-time route state with `BrokerInfo` 
(cluster, brokerName, brokerAddrs map) and `QueueInfo` (brokerName, 
readQueueNums, writeQueueNums, perm) inner classes |
   
   ### Event Flow
   
   ```
   TopicRouteService Caffeine cache reload
     -> onRouteRefreshed(topic, oldView, newView)
       -> RouteChangeEventDetector.detectChanges(topic, oldRoute, newRoute)
         -> List<RouteChangeEvent>
           -> RouteChangeNotifier broadcasts to matching subscribers
             -> gRPC server-streaming response to client
   ```
   
   ### Files Changed
   
   | File | Description |
   |------|-------------|
   | `proxy/src/main/java/.../grpc/admin/RouteChangeEventDetector.java` | 
Detection engine (new, 357 lines) |
   | `proxy/src/main/java/.../grpc/admin/RouteChangeNotifier.java` | Subscriber 
management and broadcasting (new, 245 lines) |
   | `proxy/src/main/java/.../grpc/admin/model/RouteChangeEvent.java` | Event 
POJO (new, 136 lines) |
   | `proxy/src/main/java/.../grpc/admin/model/RouteChangeEventType.java` | 
6-value enum (new, 31 lines) |
   | `proxy/src/main/java/.../grpc/admin/model/TopicRouteSnapshot.java` | Route 
snapshot POJO (new, 138 lines) |
   | `proxy/src/main/java/.../service/route/TopicRouteService.java` | 
RouteRefreshListener interface + cache reload notification (+74 lines) |
   | `proxy/src/test/java/.../grpc/admin/RouteChangeEventDetectorTest.java` | 
20 test methods (new, 610 lines) |
   | `proxy/src/test/java/.../grpc/admin/RouteChangeNotifierTest.java` | 
Subscriber/broadcast tests (new, 531 lines) |
   | `proxy/src/test/java/.../grpc/admin/model/RouteChangeEventTest.java` | 
Event model tests (new, 138 lines) |
   | `proxy/src/test/java/.../grpc/admin/model/RouteChangeEventTypeTest.java` | 
Enum tests (new, 100 lines) |
   | `proxy/src/test/java/.../grpc/admin/model/TopicRouteSnapshotTest.java` | 
Snapshot model tests (new, 155 lines) |
   
   ### Design Decisions
   
   - **Passive detection**: Events are detected by comparing route snapshots 
during the existing Caffeine cache reload cycle (~20s default), avoiding 
additional network probes or broker polling.
   - **Initial snapshot on subscribe**: New subscribers receive a 
`ROUTE_SNAPSHOT` event containing the current route state for all cached 
topics, enabling clients to build a complete initial view before processing 
incremental changes.
   - **Filter support**: Subscribers can filter by topic list and/or event 
type, reducing unnecessary network traffic for clients interested in specific 
changes.
   - **Thread safety**: `CopyOnWriteArrayList` for subscribers ensures safe 
concurrent access during route refresh callbacks, which may fire from multiple 
cache reload threads.
   


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

Reply via email to