Search in sources :

Example 1 with SimpleLoadBalancerStateListener

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);
                }
            }
        }
    });
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) TransportClient(com.linkedin.r2.transport.common.bridge.client.TransportClient) LoadBalancerClusterListener(com.linkedin.d2.balancer.LoadBalancerClusterListener) PropertyEvent(com.linkedin.d2.discovery.event.PropertyEventThread.PropertyEvent) RelativeLoadBalancerStrategy(com.linkedin.d2.balancer.strategies.relative.RelativeLoadBalancerStrategy) LoadBalancerStrategy(com.linkedin.d2.balancer.strategies.LoadBalancerStrategy) PropertyEventShutdownCallback(com.linkedin.d2.discovery.event.PropertyEventThread.PropertyEventShutdownCallback) Callback(com.linkedin.common.callback.Callback) SimpleCallback(com.linkedin.common.callback.SimpleCallback) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) None(com.linkedin.common.util.None) SimpleCallback(com.linkedin.common.callback.SimpleCallback)

Example 2 with SimpleLoadBalancerStateListener

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);
        }
    });
}
Also used : PropertyEvent(com.linkedin.d2.discovery.event.PropertyEventThread.PropertyEvent)

Example 3 with SimpleLoadBalancerStateListener

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());
            }
        }
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) LoadBalancerStrategy(com.linkedin.d2.balancer.strategies.LoadBalancerStrategy) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 4 with SimpleLoadBalancerStateListener

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";
        }
    });
}
Also used : SimpleLoadBalancerStateListener(com.linkedin.d2.balancer.simple.SimpleLoadBalancerState.SimpleLoadBalancerStateListener) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) LoadBalancerStrategy(com.linkedin.d2.balancer.strategies.LoadBalancerStrategy)

Example 5 with SimpleLoadBalancerStateListener

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);
                    }
                }
            }
        }
    }
}
Also used : TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) URI(java.net.URI)

Aggregations

TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)4 LoadBalancerStrategy (com.linkedin.d2.balancer.strategies.LoadBalancerStrategy)3 PropertyEvent (com.linkedin.d2.discovery.event.PropertyEventThread.PropertyEvent)3 TransportClient (com.linkedin.r2.transport.common.bridge.client.TransportClient)2 URI (java.net.URI)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Callback (com.linkedin.common.callback.Callback)1 SimpleCallback (com.linkedin.common.callback.SimpleCallback)1 None (com.linkedin.common.util.None)1 LoadBalancerClusterListener (com.linkedin.d2.balancer.LoadBalancerClusterListener)1 SimpleLoadBalancerStateListener (com.linkedin.d2.balancer.simple.SimpleLoadBalancerState.SimpleLoadBalancerStateListener)1 RelativeLoadBalancerStrategy (com.linkedin.d2.balancer.strategies.relative.RelativeLoadBalancerStrategy)1 PropertyEventShutdownCallback (com.linkedin.d2.discovery.event.PropertyEventThread.PropertyEventShutdownCallback)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1