use of com.linkedin.d2.balancer.simple.SimpleLoadBalancerState.SimpleLoadBalancerStateListener in project rest.li by linkedin.
the class SimpleLoadBalancerState method shutdown.
@Override
public void shutdown(final PropertyEventShutdownCallback shutdown) {
trace(_log, "shutdown");
// shutdown all three registries, all tracker clients, and the event thread
_executor.execute(new PropertyEvent("shutdown load balancer state") {
@Override
public void innerRun() {
// Need to shutdown loadBalancerStrategies before the transportClients are shutdown
for (Map<String, LoadBalancerStrategy> strategyEntry : _serviceStrategies.values()) {
strategyEntry.values().forEach(LoadBalancerStrategy::shutdown);
}
// put all tracker clients into a single set for convenience
Set<TransportClient> transportClients = new HashSet<>();
for (Map<String, TransportClient> clientsByScheme : _serviceClients.values()) {
transportClients.addAll(clientsByScheme.values());
}
Callback<None> trackerCallback = Callbacks.countDown(Callbacks.<None>adaptSimple(new SimpleCallback() {
@Override
public void onDone() {
shutdown.done();
}
}), transportClients.size());
info(_log, "shutting down cluster clients");
for (TransportClient transportClient : transportClients) {
transportClient.shutdown(trackerCallback);
}
// so it is needed to notify all the listeners
for (SimpleLoadBalancerStateListener listener : _listeners) {
// Notify the strategy removal
for (Map.Entry<String, Map<String, LoadBalancerStrategy>> serviceStrategy : _serviceStrategies.entrySet()) {
for (Map.Entry<String, LoadBalancerStrategy> strategyEntry : serviceStrategy.getValue().entrySet()) {
listener.onStrategyRemoved(serviceStrategy.getKey(), strategyEntry.getKey(), strategyEntry.getValue());
}
// Also notify the client removal
Map<URI, TrackerClient> trackerClients = _trackerClients.get(serviceStrategy.getKey());
if (trackerClients != null) {
for (TrackerClient client : trackerClients.values()) {
listener.onClientRemoved(serviceStrategy.getKey(), client);
}
}
}
}
// When SimpleLoadBalancerStateis shutdown, all the cluster listener also need to be notified.
for (LoadBalancerClusterListener clusterListener : _clusterListeners) {
for (String clusterName : _clusterInfo.keySet()) {
clusterListener.onClusterRemoved(clusterName);
}
}
}
});
}
use of com.linkedin.d2.balancer.simple.SimpleLoadBalancerState.SimpleLoadBalancerStateListener in project rest.li by linkedin.
the class SimpleLoadBalancerState method unregister.
public void unregister(final SimpleLoadBalancerStateListener listener) {
trace(_log, "unregister listener: ", listener);
_executor.execute(new PropertyEvent("remove listener for state") {
@Override
public void innerRun() {
_listeners.remove(listener);
}
});
}
use of com.linkedin.d2.balancer.simple.SimpleLoadBalancerState.SimpleLoadBalancerStateListener in project rest.li by linkedin.
the class SimpleLoadBalancerState method refreshServiceStrategies.
void refreshServiceStrategies(ServiceProperties serviceProperties) {
info(_log, "refreshing service strategies for service: ", serviceProperties);
List<String> strategyList = serviceProperties.getLoadBalancerStrategyList();
LoadBalancerStrategyFactory<? extends LoadBalancerStrategy> factory = null;
if (strategyList != null && !strategyList.isEmpty()) {
// waiting for all clients to update their code level before any clients can use it.
for (String strategy : strategyList) {
factory = _loadBalancerStrategyFactories.get(strategy);
if (factory != null) {
break;
}
}
}
// to refreshServiceStrategies without the strategy existing yet.
if (factory == null) {
warn(_log, "No valid strategy found. ", serviceProperties);
}
Map<String, LoadBalancerStrategy> strategyMap = new ConcurrentHashMap<String, LoadBalancerStrategy>();
if (factory != null && serviceProperties.getPrioritizedSchemes() != null && !serviceProperties.getPrioritizedSchemes().isEmpty()) {
List<String> schemes = serviceProperties.getPrioritizedSchemes();
for (String scheme : schemes) {
Map<String, Object> loadBalancerStrategyProperties = new HashMap<String, Object>(serviceProperties.getLoadBalancerStrategyProperties());
// Save the service path as a property -- Quarantine may need this info to construct correct
// health checking path
loadBalancerStrategyProperties.put(PropertyKeys.PATH, serviceProperties.getPath());
LoadBalancerStrategy strategy = factory.newLoadBalancer(serviceProperties.getServiceName(), loadBalancerStrategyProperties, serviceProperties.getDegraderProperties());
strategyMap.put(scheme, strategy);
}
} else {
warn(_log, "unable to find cluster or factory for ", serviceProperties, ": ", factory);
}
Map<String, LoadBalancerStrategy> oldStrategies = _serviceStrategies.put(serviceProperties.getServiceName(), strategyMap);
_serviceStrategiesCache.remove(serviceProperties.getServiceName());
info(_log, "removing strategies ", serviceProperties.getServiceName(), ": ", oldStrategies);
info(_log, "putting strategies ", serviceProperties.getServiceName(), ": ", strategyMap);
// notify listeners of the removed strategy
if (oldStrategies != null) {
// shutdown strategies before notification
oldStrategies.values().forEach(LoadBalancerStrategy::shutdown);
for (SimpleLoadBalancerStateListener listener : _listeners) {
for (Map.Entry<String, LoadBalancerStrategy> oldStrategy : oldStrategies.entrySet()) {
listener.onStrategyRemoved(serviceProperties.getServiceName(), oldStrategy.getKey(), oldStrategy.getValue());
}
}
}
// they will get confused and remove what was just added.
if (!strategyMap.isEmpty()) {
for (SimpleLoadBalancerStateListener listener : _listeners) {
// notify listeners of the added strategy
for (Map.Entry<String, LoadBalancerStrategy> newStrategy : strategyMap.entrySet()) {
listener.onStrategyAdded(serviceProperties.getServiceName(), newStrategy.getKey(), newStrategy.getValue());
}
}
}
}
use of com.linkedin.d2.balancer.simple.SimpleLoadBalancerState.SimpleLoadBalancerStateListener in project rest.li by linkedin.
the class D2ClientJmxManager method setSimpleLoadBalancerState.
public void setSimpleLoadBalancerState(SimpleLoadBalancerState state) {
_jmxManager.registerLoadBalancerState(_prefix + "-LoadBalancerState", state);
state.register(new SimpleLoadBalancerStateListener() {
@Override
public void onStrategyAdded(String serviceName, String scheme, LoadBalancerStrategy strategy) {
_jmxManager.registerLoadBalancerStrategy(getLoadBalancerJmxName(serviceName, scheme), strategy);
}
@Override
public void onStrategyRemoved(String serviceName, String scheme, LoadBalancerStrategy strategy) {
_jmxManager.unregister(getLoadBalancerJmxName(serviceName, scheme));
}
@Override
public void onClientAdded(String clusterName, TrackerClient client) {
// We currently think we can make this no-op as the info provided is not helpful
// _jmxManager.checkReg(new DegraderControl((DegraderImpl) client.getDegrader(DefaultPartitionAccessor.DEFAULT_PARTITION_ID)),
// _prefix + "-" + clusterName + "-" + client.getUri().toString().replace("://", "-") + "-TrackerClient-Degrader");
}
@Override
public void onClientRemoved(String clusterName, TrackerClient client) {
// We currently think we can make this no-op as the info provided is not helpful
// _jmxManager.unregister(_prefix + "-" + clusterName + "-" + client.getUri().toString().replace("://", "-") + "-TrackerClient-Degrader");
}
private String getLoadBalancerJmxName(String serviceName, String scheme) {
return serviceName + "-" + scheme + "-LoadBalancerStrategy";
}
});
}
use of com.linkedin.d2.balancer.simple.SimpleLoadBalancerState.SimpleLoadBalancerStateListener in project rest.li by linkedin.
the class SimpleLoadBalancerState method removeTrackerClients.
void removeTrackerClients(String clusterName) {
warn(_log, "removing all tracker clients for cluster: ", clusterName);
Set<String> serviceNames = _servicesPerCluster.get(clusterName);
if (serviceNames != null) {
for (String serviceName : serviceNames) {
Map<URI, TrackerClient> clients = _trackerClients.remove(serviceName);
if (clients != null) {
for (TrackerClient client : clients.values()) {
// notify listeners of the removed client
for (SimpleLoadBalancerStateListener listener : _listeners) {
listener.onClientRemoved(serviceName, client);
}
}
}
}
}
}
Aggregations