func (r *RoundRobin) NextEndpoint(req request.Request) (endpoint.Endpoint, error) { r.mutex.Lock() defer r.mutex.Unlock() e, err := r.nextEndpoint(req) if err != nil { return nil, err } lastAttempt := req.GetLastAttempt() // This is the first try, so just return the selected endpoint if lastAttempt == nil { return e, nil } // Try to prevent failover to the same endpoint that we've seen before, // that reduces the probability of the scenario when failover hits same endpoint // on the next attempt and fails, so users will see a failed request. var endpoint endpoint.Endpoint for _ = range r.endpoints { endpoint, err = r.nextEndpoint(req) if err != nil { return nil, err } if !hasAttempted(req, endpoint) { return endpoint, nil } } return endpoint, nil }