use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerStrategyV3 method getTrackerClient.
@Override
public TrackerClient getTrackerClient(Request request, RequestContext requestContext, long clusterGenerationId, int partitionId, List<TrackerClient> trackerClients) {
debug(_log, "getTrackerClient with generation id ", clusterGenerationId, " partition id: ", partitionId, " on tracker clients: ", trackerClients);
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 updatePartitionState for any partition
checkUpdatePartitionState(clusterGenerationId, partitionId, trackerClients);
Ring<URI> ring = _state.getRing(partitionId);
URI targetHostUri = KeyMapper.TargetHostHints.getRequestContextTargetHost(requestContext);
Set<URI> excludedUris = ExcludedHostHints.getRequestContextExcludedHosts(requestContext);
if (excludedUris == null) {
excludedUris = new HashSet<>();
}
//no valid target host header was found in the request
TrackerClient client;
if (targetHostUri == null) {
client = findValidClientFromRing(request, ring, trackerClients, excludedUris, requestContext);
} else {
debug(_log, "Degrader honoring target host header in request, skipping hashing. URI: ", targetHostUri);
client = searchClientFromUri(targetHostUri, trackerClients);
if (client == null) {
warn(_log, "No client found for ", targetHostUri, ". Target host specified is no longer part of cluster");
}
}
boolean dropCall = client == null;
if (!dropCall) {
dropCall = client.getDegrader(partitionId).checkDrop();
if (dropCall) {
warn(_log, "client's degrader is dropping call for: ", client);
} else {
debug(_log, "returning client: ", client);
}
}
return (!dropCall) ? client : null;
}
use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class TrackerClientTest method testClientRestRequest.
@Test(groups = { "small", "back-end" })
public void testClientRestRequest() throws URISyntaxException {
URI uri = URI.create("http://test.qa.com:1234/foo");
double weight = 3d;
TestClient wrappedClient = new TestClient();
Clock clock = new SettableClock();
Map<Integer, PartitionData> partitionDataMap = new HashMap<Integer, PartitionData>(2);
partitionDataMap.put(DefaultPartitionAccessor.DEFAULT_PARTITION_ID, new PartitionData(3d));
TrackerClient client = new TrackerClient(uri, partitionDataMap, wrappedClient, clock, null);
assertEquals(client.getUri(), uri);
Double clientWeight = client.getPartitionWeight(DefaultPartitionAccessor.DEFAULT_PARTITION_ID);
assertEquals(clientWeight, weight);
assertEquals(client.getWrappedClient(), wrappedClient);
RestRequest restRequest = new RestRequestBuilder(uri).build();
Map<String, String> restWireAttrs = new HashMap<String, String>();
TestTransportCallback<RestResponse> restCallback = new TestTransportCallback<RestResponse>();
client.restRequest(restRequest, new RequestContext(), restWireAttrs, restCallback);
assertFalse(restCallback.response.hasError());
assertEquals(wrappedClient.restRequest, restRequest);
assertEquals(wrappedClient.restWireAttrs, restWireAttrs);
}
use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class TrackerClientTest method createTrackerClient.
private TrackerClient createTrackerClient(TransportClient tc, Clock clock, URI uri) {
double weight = 3d;
Map<Integer, PartitionData> partitionDataMap = new HashMap<Integer, PartitionData>(2);
partitionDataMap.put(DefaultPartitionAccessor.DEFAULT_PARTITION_ID, new PartitionData(3d));
DegraderImpl.Config config = new DegraderImpl.Config();
config.setHighErrorRate(0.1);
config.setLowErrorRate(0.0);
config.setMinCallCount(1);
return new TrackerClient(uri, partitionDataMap, tc, clock, config);
}
use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerStrategyV2_1 method getUnhealthyTrackerClients.
private static List<String> getUnhealthyTrackerClients(List<TrackerClientUpdater> trackerClientUpdaters, Map<URI, Integer> pointsMap, DegraderLoadBalancerStrategyConfig config) {
List<String> unhealthyClients = new ArrayList<String>();
for (TrackerClientUpdater clientUpdater : trackerClientUpdaters) {
TrackerClient client = clientUpdater.getTrackerClient();
int perfectHealth = (int) (client.getPartitionWeight(DEFAULT_PARTITION_ID) * config.getPointsPerWeight());
Integer point = pointsMap.get(client.getUri());
if (point < perfectHealth) {
unhealthyClients.add(client.getUri() + ":" + point + "/" + perfectHealth);
}
}
return unhealthyClients;
}
use of com.linkedin.d2.balancer.clients.TrackerClient in project rest.li by linkedin.
the class DegraderLoadBalancerStrategyV2_1 method getTrackerClient.
@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);
Set<URI> excludedUris = ExcludedHostHints.getRequestContextExcludedHosts(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
Ring<URI> ring = _state.getRing();
Iterator<URI> iterator = ring.getIterator(hashCode);
while (iterator.hasNext() && targetHostUri == null) {
URI uri = iterator.next();
if (excludedUris == null || !excludedUris.contains(uri)) {
targetHostUri = uri;
}
}
ExcludedHostHints.addRequestContextExcludedHost(requestContext, targetHostUri);
} else {
debug(_log, "Degrader honoring target host header in request, skipping hashing. URI: " + targetHostUri.toString());
}
TrackerClient client = null;
if (targetHostUri != null) {
// 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;
}
Aggregations