use of com.linkedin.d2.balancer.LoadBalancerStateItem in project rest.li by linkedin.
the class UriLoadBalancerSubscriber method handlePut.
@Override
protected void handlePut(final String cluster, final UriProperties uriProperties) {
// add tracker clients for uris that we aren't already tracking
if (uriProperties != null) {
String clusterName = uriProperties.getClusterName();
Set<String> serviceNames = _simpleLoadBalancerState.getServicesPerCluster().get(clusterName);
// updates all the services that these uris provide
if (serviceNames != null) {
for (String serviceName : serviceNames) {
Map<URI, TrackerClient> trackerClients = _simpleLoadBalancerState.getTrackerClients().get(serviceName);
if (trackerClients == null) {
trackerClients = new ConcurrentHashMap<>();
_simpleLoadBalancerState.getTrackerClients().put(serviceName, trackerClients);
}
for (URI uri : uriProperties.Uris()) {
Map<Integer, PartitionData> partitionDataMap = uriProperties.getPartitionDataMap(uri);
TrackerClient client = trackerClients.get(uri);
Optional<Map<String, Object>> newUriSpecificProperties = Optional.ofNullable(uriProperties.getUriSpecificProperties()).map(uriSpecificProperties -> uriSpecificProperties.get(uri));
Optional<Map<String, Object>> oldUriSpecificProperties = Optional.ofNullable(_simpleLoadBalancerState.getUriProperties(clusterName)).map(LoadBalancerStateItem::getProperty).map(UriProperties::getUriSpecificProperties).map(uriSpecificProperties -> uriSpecificProperties.get(uri));
if (client == null || !client.getPartitionDataMap().equals(partitionDataMap) || !newUriSpecificProperties.equals(oldUriSpecificProperties)) {
client = _simpleLoadBalancerState.buildTrackerClient(uri, uriProperties, serviceName);
if (client != null) {
debug(_log, "adding new tracker client from updated uri properties: ", client);
// notify listeners of the added client
for (SimpleLoadBalancerState.SimpleLoadBalancerStateListener listener : _simpleLoadBalancerState.getListeners()) {
listener.onClientAdded(serviceName, client);
}
trackerClients.put(uri, client);
}
}
}
}
}
}
// replace the URI properties
_simpleLoadBalancerState.getUriProperties().put(cluster, new LoadBalancerStateItem<>(uriProperties, _simpleLoadBalancerState.getVersionAccess().incrementAndGet(), System.currentTimeMillis()));
// now remove URIs that we're tracking, but have been removed from the new uri properties
if (uriProperties != null) {
Set<String> serviceNames = _simpleLoadBalancerState.getServicesPerCluster().get(uriProperties.getClusterName());
if (serviceNames != null) {
for (String serviceName : serviceNames) {
Map<URI, TrackerClient> trackerClients = _simpleLoadBalancerState.getTrackerClients().get(serviceName);
if (trackerClients != null) {
for (Iterator<URI> it = trackerClients.keySet().iterator(); it.hasNext(); ) {
URI uri = it.next();
if (!uriProperties.Uris().contains(uri)) {
TrackerClient client = trackerClients.remove(uri);
debug(_log, "removing dead tracker client: ", client);
for (SimpleLoadBalancerState.SimpleLoadBalancerStateListener listener : _simpleLoadBalancerState.getListeners()) {
listener.onClientRemoved(serviceName, client);
}
}
}
}
}
}
} else {
// uri properties was null, we'll just log the event and continues.
// The reasoning is we might receive a null event when there's a problem writing/reading
// cache file, or we just started listening to a cluster without any uris yet.
warn(_log, "received a null uri properties for cluster: ", cluster);
}
}
use of com.linkedin.d2.balancer.LoadBalancerStateItem in project rest.li by linkedin.
the class ServiceLoadBalancerSubscriber method handlePut.
@Override
protected void handlePut(final String listenTo, final ServiceProperties discoveryProperties) {
// TODO: pick stable or canary configs if canary exists
LoadBalancerStateItem<ServiceProperties> oldServicePropertiesItem = _simpleLoadBalancerState.getServiceProperties().get(listenTo);
_simpleLoadBalancerState.getServiceProperties().put(listenTo, new LoadBalancerStateItem<>(discoveryProperties, _simpleLoadBalancerState.getVersionAccess().incrementAndGet(), System.currentTimeMillis()));
// always refresh strategies when we receive service event
if (discoveryProperties != null) {
// this service is no longer hosted in the old cluster.
if (oldServicePropertiesItem != null) {
ServiceProperties oldServiceProperties = oldServicePropertiesItem.getProperty();
if (oldServiceProperties != null && oldServiceProperties.getClusterName() != null && !oldServiceProperties.getClusterName().equals(discoveryProperties.getClusterName())) {
Set<String> serviceNames = _simpleLoadBalancerState.getServicesPerCluster().get(oldServiceProperties.getClusterName());
if (serviceNames != null) {
serviceNames.remove(oldServiceProperties.getServiceName());
}
}
}
_simpleLoadBalancerState.refreshServiceStrategies(discoveryProperties);
_simpleLoadBalancerState.refreshClients(discoveryProperties);
// refresh state for which services are on which clusters
Set<String> serviceNames = _simpleLoadBalancerState.getServicesPerCluster().get(discoveryProperties.getClusterName());
if (serviceNames == null) {
serviceNames = Collections.newSetFromMap(new ConcurrentHashMap<>());
_simpleLoadBalancerState.getServicesPerCluster().put(discoveryProperties.getClusterName(), serviceNames);
}
serviceNames.add(discoveryProperties.getServiceName());
} else if (oldServicePropertiesItem != null) {
// if we've replaced a service properties with null, update the cluster ->
// service state that the service is no longer on its cluster.
ServiceProperties oldServiceProperties = oldServicePropertiesItem.getProperty();
if (oldServiceProperties != null) {
Set<String> serviceNames = _simpleLoadBalancerState.getServicesPerCluster().get(oldServiceProperties.getClusterName());
if (serviceNames != null) {
serviceNames.remove(oldServiceProperties.getServiceName());
}
}
}
if (discoveryProperties == null) {
// we'll just ignore the event and move on.
// we could receive a null if the file store properties cannot read/write a file.
// in this case it's better to leave the state intact and not do anything
_log.warn("We receive a null service properties for {}. ", listenTo);
}
}
Aggregations