Aias00 commented on code in PR #7260:
URL: https://github.com/apache/shenyu/pull/7260#discussion_r4110269301


##########
shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepository.java:
##########
@@ -238,11 +241,16 @@ private <T> void doHeartbeat(final T t, final String 
path) {
                 RegisterUtils.doHeartBeat(GsonUtils.getInstance().toJson(t), 
concat, Constants.HEARTBEAT, accessToken);
             } catch (Exception e) {
                 LOGGER.error("HeartBeat admin url :{} is fail, will retry.", 
server, e);
-                if (i == serverList.size()) {
-                    throw new RuntimeException(e);
+                if (Objects.isNull(failure)) {
+                    failure = new RuntimeException(e);
+                } else {
+                    failure.addSuppressed(e);
                 }
             }
         }
+        if (Objects.nonNull(failure)) {

Review Comment:
   Request changes - see review body. This exception has nowhere to go.
   
   The heartbeat path has no retry queue and no exception boundary between here 
and the scheduler:
   
   ```
   ShenyuClientURIExecutorSubscriber.java:74    executor.scheduleAtFixedRate(() 
-> uris.forEach(this::sendHeartbeat), 30, 10, SECONDS)
   ShenyuClientURIExecutorSubscriber.java:126   private void sendHeartbeat(...) 
{ repository.sendHeartbeat(uri); }   // no try/catch
   HttpClientRegisterRepository.java:138-143   public void 
sendHeartbeat(URIRegisterDTO dto) { doHeartbeat(dto, URI_PATH); }
   HttpClientRegisterRepository.java:251       throw failure;      // NEW: 
fires when ANY server failed
   ```
   
   `ScheduledThreadPoolExecutor` suppresses all future runs of a periodic task 
once it throws. Reproduced with two admins, one down, 50 ms period, 1 s window 
(~20 expected ticks):
   
   ```
   master rule (throw only when the LAST server failed): executed 21 ticks, 
threw 0
   this patch  (throw when ANY server failed):           executed  1 tick,  
threw 1
   ```
   
   One failover drill stops this client's heartbeats permanently, until the 
process restarts; admin then ages the URI out and stops routing to it. It also 
aborts `uris.forEach` mid-cycle, so every other registered URI loses that beat 
too.
   
   In fairness the hazard exists on master as well - when the *last* server 
fails - but this patch promotes a rare edge case to the common path.
   
   Two acceptable fixes: (a) do not throw from `doHeartbeat` at all, keeping 
the accumulation only in `doRegister` where 
`FailbackRegistryRepository.java:77-82` really does catch it and enqueue a 
retry; or (b) keep throwing and wrap each URI's heartbeat in try/catch inside 
the scheduled body, which also fixes the missing per-URI isolation.
   



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