bitflicker64 commented on code in PR #3362:
URL: https://github.com/apache/hugegraph/pull/3362#discussion_r4306903938


##########
hugegraph-store/hg-store-core/src/main/java/org/apache/hugegraph/store/HeartbeatService.java:
##########
@@ -200,10 +208,61 @@ protected void registerStore() {
             
this.storeInfo.setStoreAddress(IpUtil.getNearestAddress(options.getGrpcAddress()));
             
this.storeInfo.setRaftAddress(IpUtil.getNearestAddress(options.getRaftAddress()));
 
-            long storeId = pdProvider.registerStore(this.storeInfo);
+            // Recovery is needed once per process, not when an established 
stream reconnects.
+            boolean restoring = !restored;
+            this.storeInfo.setState(restoring ? Metapb.StoreState.Offline : 
Metapb.StoreState.Up);
+            long storeId;
+            try {
+                storeId = pdProvider.registerStore(this.storeInfo);
+            } finally {
+                // Retry registration after a failure instead of heartbeating 
an unregistered Store.
+                this.storeInfo.setState(Metapb.StoreState.Offline);
+            }
             if (storeId != 0) {
                 storeInfo.setId(storeId);
                 storeMetadata.save(storeInfo);
+                if (restoring && storeEngine != null) {
+                    this.clusterStats = pdProvider.getClusterStats();
+                    timerNextDelay = REGISTER_RETRY_INTERVAL * 1000;
+                    if (restoreTask == null) {
+                        restoreTask = new FutureTask<>(() -> {
+                            storeEngine.stateChanged(storeInfo, 
Metapb.StoreState.Offline, Metapb.StoreState.Up);
+                            return null;
+                        });
+                        restoreThread = new Thread(restoreTask, 
"store-partition-restore");
+                        restoreThread.start();
+                        return;
+                    }
+                    if (!restoreTask.isDone()) {
+                        return;
+                    }
+                    try {
+                        restoreTask.get();
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().interrupt();
+                        return;
+                    } catch (ExecutionException e) {
+                        log.error("Store {} remains Offline after partition 
restore failed", storeId, e);
+                        restoreTask = null;

Review Comment:
   Minor: A restore that keeps failing is retried in full about once a second, 
with no backoff, for as long as the failure lasts.
   
   After the `ExecutionException`, `restoreTask` is cleared, and 
`timerNextDelay` is still the 1 s set at line 226. The next tick registers 
Offline again and starts a new `store-partition-restore` thread. That thread 
re-runs `loadPartition`, `syncPartitionsFromPD` and `createPartitionEngine` for 
every partition. Each failed round logs this error, with one suppressed stack 
trace per failed partition.
   
   Separately, every tick during restore, failed or just slow, sends a full 
`RegisterStore`. The Store logs `registerStore pd=...` at INFO 
(`DefaultPdProvider` line 132). PD rewrites the Store record and the keepalive 
entry and logs `Store register, id = ...` at INFO (`StoreNodeService.register`, 
lines 209 to 229). The keepalive entry lives 300 s by default 
(`store.keepAlive-timeout`), so renewing it every second is far more often than 
needed.
   
   Take one partition that cannot be restored, the case this PR deliberately 
keeps Offline. The Store then logs the same set of stack traces every second 
until someone fixes the data. Before this PR, the failure was logged once per 
restore attempt, and attempts happened only at startup and on stream reconnects.
   
   Requested change: back off restore retries after a failure, for example 
doubling the delay up to `storeHBInterval`. Log the full aggregate trace only 
on the first failure or when the set of failed partitions changes. While the 
worker is still running, polling it every second is fine, but send the Offline 
registration only every few seconds, well inside the keepalive timeout.



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