use of com.linkedin.d2.balancer.LoadBalancerStateItem in project rest.li by linkedin.
the class ZKDeterministicSubsettingMetadataProvider method getSubsettingMetadata.
@Override
public DeterministicSubsettingMetadata getSubsettingMetadata(LoadBalancerState state) {
FutureCallback<DeterministicSubsettingMetadata> metadataFutureCallback = new FutureCallback<>();
state.listenToCluster(_clusterName, (type, name) -> {
LoadBalancerStateItem<UriProperties> uriItem = state.getUriProperties(_clusterName);
synchronized (_lock) {
if (uriItem.getVersion() != _peerClusterVersion) {
_peerClusterVersion = uriItem.getVersion();
UriProperties uriProperties = uriItem.getProperty();
if (uriProperties != null) {
// Sort the URIs so each client sees the same ordering
List<String> sortedHosts = uriProperties.getPartitionDesc().keySet().stream().map(URI::getHost).sorted().distinct().collect(Collectors.toList());
int instanceId = sortedHosts.indexOf(_hostName);
if (instanceId >= 0) {
_subsettingMetadata = new DeterministicSubsettingMetadata(instanceId, sortedHosts.size(), _peerClusterVersion);
} else {
_subsettingMetadata = null;
}
} else {
_subsettingMetadata = null;
}
_log.debug("Got deterministic subsetting metadata for cluster {}: {}", _clusterName, _subsettingMetadata);
}
}
metadataFutureCallback.onSuccess(_subsettingMetadata);
});
try {
return metadataFutureCallback.get(_timeout, _unit);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
_log.warn("Failed to fetch deterministic subsetting metadata from ZooKeeper for cluster " + _clusterName, e);
return null;
}
}
use of com.linkedin.d2.balancer.LoadBalancerStateItem in project rest.li by linkedin.
the class SimpleLoadBalancerState method refreshClients.
/**
* Creates new {@link TrackerClient} and {@link TransportClient} for service and shut down any old ones.
*
* @param serviceProperties
*/
void refreshClients(ServiceProperties serviceProperties) {
String serviceName = serviceProperties.getServiceName();
Map<String, TransportClient> newTransportClients = createTransportClients(serviceProperties);
// clients-by-scheme map is never edited, only replaced.
newTransportClients = Collections.unmodifiableMap(newTransportClients);
Map<String, TransportClient> oldTransportClients = _serviceClients.put(serviceName, newTransportClients);
Map<URI, TrackerClient> newTrackerClients;
// update all tracker clients to use new configs
LoadBalancerStateItem<UriProperties> uriItem = _uriProperties.get(serviceProperties.getClusterName());
UriProperties uriProperties = uriItem == null ? null : uriItem.getProperty();
if (uriProperties != null) {
Set<URI> uris = uriProperties.Uris();
newTrackerClients = new ConcurrentHashMap<>(CollectionUtils.getMapInitialCapacity(uris.size(), 0.75f), 0.75f, 1);
for (URI uri : uris) {
TrackerClient trackerClient = buildTrackerClient(uri, uriProperties, serviceName, serviceProperties);
if (trackerClient != null) {
newTrackerClients.put(uri, trackerClient);
}
}
} else {
newTrackerClients = new ConcurrentHashMap<>();
}
_trackerClients.put(serviceName, newTrackerClients);
shutdownTransportClients(oldTransportClients, serviceName);
}
use of com.linkedin.d2.balancer.LoadBalancerStateItem in project rest.li by linkedin.
the class SimpleLoadBalancerState method buildTrackerClient.
@Nullable
public TrackerClient buildTrackerClient(URI uri, UriProperties uriProperties, String serviceName) {
LoadBalancerStateItem<ServiceProperties> servicePropertiesItem = _serviceProperties.get(serviceName);
ServiceProperties serviceProperties = servicePropertiesItem == null ? null : servicePropertiesItem.getProperty();
return buildTrackerClient(uri, uriProperties, serviceName, serviceProperties);
}
use of com.linkedin.d2.balancer.LoadBalancerStateItem in project rest.li by linkedin.
the class SimpleLoadBalancer method getRings.
public Map<Integer, Ring<URI>> getRings(URI serviceUri) throws ServiceUnavailableException {
ServiceProperties service = listenToServiceAndCluster(serviceUri);
String serviceName = service.getServiceName();
String clusterName = service.getClusterName();
ClusterProperties cluster = getClusterProperties(serviceName, clusterName);
LoadBalancerStateItem<UriProperties> uriItem = getUriItem(serviceName, clusterName, cluster);
UriProperties uris = uriItem.getProperty();
List<LoadBalancerState.SchemeStrategyPair> orderedStrategies = _state.getStrategiesForService(serviceName, service.getPrioritizedSchemes());
if (!orderedStrategies.isEmpty()) {
final PartitionAccessor accessor = getPartitionAccessor(serviceName, clusterName);
int maxPartitionId = accessor.getMaxPartitionId();
Map<Integer, Ring<URI>> ringMap = new HashMap<>((maxPartitionId + 1) * 2);
for (int partitionId = 0; partitionId <= maxPartitionId; partitionId++) {
for (LoadBalancerState.SchemeStrategyPair pair : orderedStrategies) {
TrackerClientSubsetItem subsetItem = getPotentialClients(serviceName, service, cluster, uris, pair.getScheme(), partitionId, uriItem.getVersion());
Ring<URI> ring = pair.getStrategy().getRing(uriItem.getVersion(), partitionId, subsetItem.getWeightedSubset(), subsetItem.shouldForceUpdate());
// ring will never be null; it can be empty
ringMap.put(partitionId, ring);
if (!ring.isEmpty()) {
// don't fallback to the next strategy if there are already hosts in the current one
break;
}
}
}
return ringMap;
} else {
throw new ServiceUnavailableException(serviceName, "PEGA_1003. Unable to find a load balancer strategy" + "Server Schemes: [" + String.join(", ", service.getPrioritizedSchemes()) + ']');
}
}
use of com.linkedin.d2.balancer.LoadBalancerStateItem in project rest.li by linkedin.
the class SimpleLoadBalancer method getLoadBalancedServiceProperties.
public void getLoadBalancedServiceProperties(String serviceName, boolean waitForUpdatedValue, Callback<ServiceProperties> servicePropertiesCallback) {
Runnable callback = () -> {
LoadBalancerStateItem<ServiceProperties> serviceItem = _state.getServiceProperties(serviceName);
if (serviceItem == null || serviceItem.getProperty() == null) {
warn(_log, "unable to find service: ", serviceName);
die(servicePropertiesCallback, serviceName, "PEGA_1012. no service properties in lb state");
return;
}
debug(_log, "got service: ", serviceItem);
servicePropertiesCallback.onSuccess(serviceItem.getProperty());
};
if (waitForUpdatedValue) {
_state.listenToService(serviceName, (type, name) -> callback.run());
} else {
_log.info("No timeout for service {}", serviceName);
_state.listenToService(serviceName, new NullStateListenerCallback());
callback.run();
}
}
Aggregations