Search in sources :

Example 11 with LoadBalancerStateItem

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;
    }
}
Also used : UriProperties(com.linkedin.d2.balancer.properties.UriProperties) ExecutionException(java.util.concurrent.ExecutionException) FutureCallback(com.linkedin.common.callback.FutureCallback) TimeoutException(java.util.concurrent.TimeoutException)

Example 12 with LoadBalancerStateItem

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);
}
Also used : TransportClient(com.linkedin.r2.transport.common.bridge.client.TransportClient) TrackerClient(com.linkedin.d2.balancer.clients.TrackerClient) UriProperties(com.linkedin.d2.balancer.properties.UriProperties) URI(java.net.URI)

Example 13 with LoadBalancerStateItem

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);
}
Also used : ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) Nullable(javax.annotation.Nullable)

Example 14 with LoadBalancerStateItem

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()) + ']');
    }
}
Also used : HashMap(java.util.HashMap) ServiceUnavailableException(com.linkedin.d2.balancer.ServiceUnavailableException) URI(java.net.URI) LoadBalancerState(com.linkedin.d2.balancer.LoadBalancerState) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) PartitionAccessor(com.linkedin.d2.balancer.util.partitions.PartitionAccessor) UriProperties(com.linkedin.d2.balancer.properties.UriProperties) Ring(com.linkedin.d2.balancer.util.hashing.Ring) ClusterProperties(com.linkedin.d2.balancer.properties.ClusterProperties)

Example 15 with LoadBalancerStateItem

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();
    }
}
Also used : NullStateListenerCallback(com.linkedin.d2.balancer.LoadBalancerState.NullStateListenerCallback) LoadBalancerStateItem(com.linkedin.d2.balancer.LoadBalancerStateItem)

Aggregations

URI (java.net.URI)11 UriProperties (com.linkedin.d2.balancer.properties.UriProperties)10 ServiceProperties (com.linkedin.d2.balancer.properties.ServiceProperties)9 TrackerClient (com.linkedin.d2.balancer.clients.TrackerClient)7 ClusterProperties (com.linkedin.d2.balancer.properties.ClusterProperties)7 HashMap (java.util.HashMap)6 LoadBalancerState (com.linkedin.d2.balancer.LoadBalancerState)5 ServiceUnavailableException (com.linkedin.d2.balancer.ServiceUnavailableException)5 PartitionAccessor (com.linkedin.d2.balancer.util.partitions.PartitionAccessor)5 TransportClient (com.linkedin.r2.transport.common.bridge.client.TransportClient)5 Map (java.util.Map)5 Set (java.util.Set)5 PartitionData (com.linkedin.d2.balancer.properties.PartitionData)4 ArrayList (java.util.ArrayList)4 HashSet (java.util.HashSet)4 LoadBalancerStateItem (com.linkedin.d2.balancer.LoadBalancerStateItem)3 Ring (com.linkedin.d2.balancer.util.hashing.Ring)3 PartitionAccessException (com.linkedin.d2.balancer.util.partitions.PartitionAccessException)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 FutureCallback (com.linkedin.common.callback.FutureCallback)2