private static void logState( DegraderLoadBalancerState oldState, DegraderLoadBalancerState newState, DegraderLoadBalancerStrategyConfig config, List<TrackerClientUpdater> trackerClientUpdaters) { if (_log.isDebugEnabled()) { _log.debug( "Strategy updated: newState=" + newState + ", config=" + config + ", HashRing coverage=" + newState.getRing()); } else { if (!isOldStateTheSameAsNewState(oldState, newState) || !isNewStateHealthy(newState, config, trackerClientUpdaters)) { _log.info( "Strategy updated: newState=" + newState + ", oldState =" + oldState + ", new state's config=" + config); } } }
@Override public Ring<URI> getRing( long clusterGenerationId, int partitionId, List<TrackerClient> trackerClients) { if (partitionId != DEFAULT_PARTITION_ID) { throw new UnsupportedOperationException( "Trying to access partition: " + partitionId + "on an unpartitioned cluster"); } checkUpdateState(clusterGenerationId, trackerClients); return _state.getRing(); }
@Override public TrackerClient getTrackerClient( Request request, RequestContext requestContext, long clusterGenerationId, int partitionId, List<TrackerClient> trackerClients) { if (partitionId != DEFAULT_PARTITION_ID) { throw new UnsupportedOperationException( "Trying to access partition: " + partitionId + "on an unpartitioned cluster"); } debug( _log, "getTrackerClient with generation id ", clusterGenerationId, " on tracker clients: ", clusterGenerationId); if (trackerClients == null || trackerClients.size() == 0) { warn(_log, "getTrackerClient called with null/empty trackerClients, so returning null"); return null; } // only one thread will be allowed to enter updateState. checkUpdateState(clusterGenerationId, trackerClients); URI targetHostUri = KeyMapper.TargetHostHints.getRequestContextTargetHost(requestContext); URI hostHeaderUri = targetHostUri; // no valid target host header was found in the request if (targetHostUri == null) { // Compute the hash code int hashCode = _hashFunction.hash(request); // we operate only on URIs to ensure that we never hold on to an old tracker client // that the cluster manager has removed targetHostUri = _state.getRing().get(hashCode); } else { debug( _log, "Degrader honoring target host header in request, skipping hashing. URI: " + targetHostUri.toString()); } TrackerClient client = null; if (targetHostUri != null) { // These are the clients that were passed in, NOT necessarily the clients that make up the // consistent hash ring! Therefore, this linear scan is the best we can do. for (TrackerClient trackerClient : trackerClients) { if (trackerClient.getUri().equals(targetHostUri)) { client = trackerClient; break; } } if (client == null) { warn( _log, "No client found for " + targetHostUri + (hostHeaderUri == null ? ", degrader load balancer state is inconsistent with cluster manager" : ", target host specified is no longer part of cluster")); } } else { warn(_log, "unable to find a URI to use"); } boolean dropCall = client == null; if (!dropCall) { dropCall = client.getDegrader(DEFAULT_PARTITION_ID).checkDrop(); if (dropCall) { warn(_log, "client's degrader is dropping call for: ", client); } else { debug(_log, "returning client: ", client); } } return (!dropCall) ? client : null; }