imbajin commented on code in PR #3356:
URL: https://github.com/apache/hugegraph/pull/3356#discussion_r4339724925


##########
hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/TaskScheduleService.java:
##########
@@ -582,6 +630,258 @@ public synchronized Map<Integer, Long> 
balancePartitionLeader(boolean immediatel
         return results;
     }
 
+    /**
+     * The periodic entry of leader balancing. Calls balancePartitionLeader 
only when the leader
+     * count per store has drifted further apart than 
pd.balance-leader-max-skew and does not
+     * already match the planner's targets, so a balanced cluster sees no 
transfers. Skipped while
+     * a shard group is not Normal, has no recent partition heartbeat or has a 
shard that is
+     * neither Leader nor Follower, or while a store that holds a shard is not 
active, because the
+     * target distribution would include a replica that cannot take a leader. 
The plan uses the
+     * groups checked here; a group keeps its leader when this PD is no longer 
the leader, the
+     * group changed, the target or leader store has not reported for
+     * BALANCE_LEADER_REPORT_MAX_AGE, or the target trails the leader by the 
time the transfer
+     * would be sent.
+     *
+     * @return shard group id -> the store id its leader was moved to; empty 
when skipped
+     */
+    public synchronized Map<Integer, Long> autoBalancePartitionLeader() throws 
PDException {
+        // init() does not schedule this with a negative skew, which would 
balance every run
+        int maxSkew = pdConfig.getBalanceLeaderMaxSkew();
+        if (!isLeader() || maxSkew < 0) {
+            lastLeaderIndexReports.clear();
+            earlierLeaderIndexReports.clear();
+            return new HashMap<>();
+        }
+
+        List<Metapb.ShardGroup> shardGroups = storeService.getShardGroups();
+        if (shardGroups.isEmpty()) {
+            return new HashMap<>();
+        }
+
+        List<Metapb.Store> stores = storeService.getActiveStores();

Review Comment:
   ⚠️ Important: `getActiveStores()` reads TTL-backed snapshots. When an online 
Store changes to `Exiting`, `StoreNodeService.updateStore()` leaves its TTL 
entry in place and the Exiting heartbeat path does not refresh it; 
`storeTurnoff()` can rebuild shard membership from that same list, and 
`reallocShards()` can add the Exiting Store back as a shard. Once that group is 
Normal and the shard is a Follower, this periodic path can select it and move a 
leader back to a Store being drained. Please exclude Stores whose current 
persisted state is `Exiting` from periodic targets and recheck that state 
immediately before dispatch.



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