mochengqian commented on code in PR #970:
URL: https://github.com/apache/dubbo-go-pixiu/pull/970#discussion_r3371911461


##########
pkg/cluster/loadbalancer/load_balancer.go:
##########
@@ -180,26 +194,53 @@ func pickEndpoint(balancer LoadBalancer, context 
PickContext, policy model.LbPol
        if cursorAfter != cursorBefore {
                atomic.AddUint32(&context.Config.PrePickEndpointIndex, 
cursorAfter-cursorBefore)
        }
-       return healthyEndpointFromSnapshot(endpoint, context.HealthyEndpoints)
+       return healthyEndpointFromSnapshot(endpoint, context)
 }
 
 func defensiveSnapshotPickContext(context PickContext) PickContext {
        defensive := context
        defensive.AllEndpoints = model.CloneEndpoints(context.AllEndpoints)
        defensive.HealthyEndpoints = 
model.CloneEndpoints(context.HealthyEndpoints)
+       defensive.HealthyByID = nil
        return defensive
 }
 
-func healthyEndpointFromSnapshot(endpoint *model.Endpoint, healthyEndpoints 
[]*model.Endpoint) *model.Endpoint {
+// healthyEndpointFromSnapshot validates that the balancer's pick is still a
+// member of the snapshot's healthy set and returns a defensive clone of the
+// snapshot-owned endpoint (never the balancer's possibly-cloned return).
+//
+// Resolution order:
+//
+//  1. O(1) by-ID recheck: when the pick carries an ID and the context exposes
+//     the snapshot's healthy-by-ID index, resolve the single indexed candidate
+//     and apply sameEndpointIdentity to it. Every snapshot endpoint carries a
+//     unique non-empty ID, so for an ID-bearing pick this is exactly the
+//     candidate the scan below would have found — without the O(N) walk
+//     (including the per-element SocketAddress.Equal in sameEndpointIdentity).
+//  2. Fallback scan: used when there is no ID index (e.g. a hand-built 
context)
+//     or the pick has no ID. Keeps the pointer-equality fast path for 
zero-copy
+//     balancers and the sameEndpointIdentity slow path (including the
+//     empty-ID / placeholder-address rules) unchanged.
+//
+// Returns nil when the pick is not present in the healthy set; the validation
+// is deliberate and must not be skipped by blindly cloning the balancer 
return.
+func healthyEndpointFromSnapshot(endpoint *model.Endpoint, context 
PickContext) *model.Endpoint {
        if endpoint == nil {
                return nil
        }
-       for _, candidate := range healthyEndpoints {
+       if endpoint.ID != "" && context.HealthyByID != nil {
+               candidate := 
context.HealthyByID.HealthyEndpointByIDForPick(endpoint.ID)
+               if candidate != nil && sameEndpointIdentity(candidate, 
endpoint) {
+                       return model.CloneEndpoint(candidate)
+               }
+               return nil

Review Comment:
   Addressed in 1e0e07f8: the HealthyByID recheck now returns the cloned 
snapshot endpoint immediately when the indexed candidate pointer is the 
balancer return (`candidate == endpoint`), preserving the zero-copy pointer 
fast path before falling back to `sameEndpointIdentity`. Added 
`TestHealthyEndpointFromSnapshotByIDPointerFastPathReturnsClone` to cover the 
by-ID pointer path.



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