btlqql opened a new pull request, #5352:
URL: https://github.com/apache/rocketmq-dashboard/pull/5352

   ### Which Issue(s) This PR Fixes
   
   - Fixes #5057
   
   ### Problem
   
   `ProxyConsumerResolver.remotingClient()` marked the shared Netty remoting 
client as started
   *before* calling `start()`, and it published the client object before the 
start had run at all:
   
   ```java
   private NettyRemotingClient remotingClient() {
       NettyRemotingClient client = remotingClient;
       if (client == null) {
           synchronized (this) {
               if (remotingClient == null) {
                   remotingClient = new NettyRemotingClient(new 
NettyClientConfig());
               }
               client = remotingClient;
           }
       }
       if (clientStarted.compareAndSet(false, true)) {
           client.start();
       }
       return client;
   }
   ```
   
   Two consequences follow from that order:
   
   - A first `start()` that throws leaves both the client object and 
`clientStarted=true` behind, so
     every later proxy query skips `start()` and keeps using the client that 
never finished
     initialising. Proxy consumer diagnostics stay "unavailable" for the whole 
process lifetime, even
     after the transient startup problem is gone.
   - A second caller can observe `clientStarted=true` while the first caller's 
`start()` is still
     running and pass that half-initialised client to `invokeSync`.
   
   `shutdownRemotingClient()` also keyed off the same flag, so a candidate 
whose start failed was
   neither published correctly nor disposed of.
   
   ### Changes
   
   
`server/src/main/java/org/apache/rocketmq/studio/provider/apache/ProxyConsumerResolver.java`
   
   - The client is now published only after `start()` returned. The 
`AtomicBoolean clientStarted` flag
     is gone: being published *is* the started state, so there is no window in 
which a client is
     visible while its startup is still running.
   - Initialisation happens under the resolver monitor (lock-free read on the 
published field first),
     so concurrent first-use callers wait for the startup instead of racing it.
   - A `start()` that throws disposes of the candidate 
(`shutdownFailedCandidateQuietly`) and rethrows;
     nothing is published, so the next request creates and starts a fresh 
client.
   - `shutdownRemotingClient()` takes the same monitor, so shutdown cannot run 
while a startup is in
     flight, and it only ever shuts down a client that was actually started.
   
   
`server/src/test/java/org/apache/rocketmq/studio/provider/apache/ProxyConsumerResolverTest.java`
   
   - 
`firstStartFailureShouldNotBeCachedAndTheNextQueryShouldStartAFreshClientTest` 
— the first client's
     `start()` throws, the failed candidate must be shut down and must not be 
reused, and the next
     query must create and start a replacement.
   - `concurrentFirstUseShouldWaitUntilTheRemotingClientStartupFinishedTest` — 
the second caller arrives
     while the first caller is still inside `start()`; it must not reach 
`invokeSync` before the
     startup finished, and only one client may be constructed.
   
   ### How Did You Test This Change?
   
   Red (test file only, production source unmodified at `6a68042f`):
   
   ```
   cd server && mvn -B -ntp test -Dtest=ProxyConsumerResolverTest
   [ERROR] Tests run: 8, Failures: 2, Errors: 0, Skipped: 0
   [ERROR]   
ProxyConsumerResolverTest.firstStartFailureShouldNotBeCachedAndTheNextQueryShouldStartAFreshClientTest:214
             Wanted but not invoked: nettyRemotingClient.shutdown();
   [ERROR]   
ProxyConsumerResolverTest.concurrentFirstUseShouldWaitUntilTheRemotingClientStartupFinishedTest:271
             expected: null but was: java.lang.IllegalStateException: proxy 
query reached the client before startup finished
   ```
   
   Green (same worktree with the fix applied):
   
   ```
   cd server && mvn -B -ntp test 
-Dtest=ProxyConsumerResolverTest,RocketMQConsumerDiagnosticsProviderTest,RocketMQMetadataProviderTest,RocketMQAdminClientImplTest
   [INFO] Tests run: 8,  Failures: 0, Errors: 0, Skipped: 0 -- in 
...ProxyConsumerResolverTest
   [INFO] Tests run: 80, Failures: 0, Errors: 0, Skipped: 0 -- in 
...RocketMQAdminClientImplTest
   [INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0 -- in 
...RocketMQConsumerDiagnosticsProviderTest
   [INFO] Tests run: 46, Failures: 0, Errors: 0, Skipped: 0 -- in 
...RocketMQMetadataProviderTest
   [INFO] Tests run: 145, Failures: 0, Errors: 0, Skipped: 0
   [INFO] BUILD SUCCESS
   [INFO] You have 0 Checkstyle violations.
   ```
   
   Both runs execute Checkstyle at `validate` with 0 violations. This is a 
focused backend run, not the
   full suite (the suite has pre-existing failures on this branch that need 
MySQL 8 / external tooling).
   
   ### Overlap disclosure
   
   An independent PR for the same issue already exists: #5255 (its predecessor 
#5058 was closed by the
   inactivity bot). This change is an independent implementation written from 
the issue and the current
   source; the overlapping part is the intent both share (publish only after a 
successful start and
   retry with a fresh client). The differences are: the started state here is 
the publication itself
   rather than a separate boolean flag, `shutdownRemotingClient()` is 
serialised with initialisation,
   and the two regressions drive the interleavings through Mockito construction 
mocking instead of a
   change to the production surface. The issue is still open and the fix is 
still absent from
   `rocketmq-studio`, which is what the red run above shows.
   
   ### Checklist
   
   - [x] One coherent bug fix; no unrelated changes
   - [x] Conventional Commit subject
   - [x] Startup-failure/retry and concurrent-first-use regressions
   - [x] No API contract change, no new UI text, no new files
   - [ ] Full CI is green
   


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