package com.jivesoftware.os.amza.client.http;
import com.google.common.collect.Maps;
import com.jivesoftware.os.amza.api.PartitionClient;
import com.jivesoftware.os.amza.api.PartitionClientProvider;
import com.jivesoftware.os.amza.api.RingPartitionProperties;
import com.jivesoftware.os.amza.api.partition.PartitionName;
import com.jivesoftware.os.amza.api.partition.PartitionProperties;
import java.util.Map;
import java.util.concurrent.ExecutorService;
/**
*
* @author jonathan.colt
*/
public class AmzaClientProvider<C, E extends Throwable> implements PartitionClientProvider {
private final PartitionClientFactory<C, E> partitionClientFactory;
private final PartitionHostsProvider partitionHostsProvider;
private final RingHostClientProvider<C, E> clientProvider;
private final ExecutorService callerThreads;
private final long awaitLeaderElectionForNMillis;
private final long debugClientCount;
private final long debugClientCountInterval;
private final Map<PartitionName, PartitionClient> cache = Maps.newConcurrentMap();
public AmzaClientProvider(PartitionClientFactory<C, E> partitionClientFactory,
PartitionHostsProvider partitionHostsProvider,
RingHostClientProvider<C, E> clientProvider,
ExecutorService callerThreads,
long awaitLeaderElectionForNMillis,
long debugClientCount,
long debugClientCountInterval) {
this.partitionClientFactory = partitionClientFactory;
this.partitionHostsProvider = partitionHostsProvider;
this.clientProvider = clientProvider;
this.callerThreads = callerThreads;
this.awaitLeaderElectionForNMillis = awaitLeaderElectionForNMillis;
this.debugClientCount = debugClientCount;
this.debugClientCountInterval = debugClientCountInterval;
}
@Override
public PartitionClient getPartition(PartitionName partitionName) throws Exception {
PartitionClient got = cache.get(partitionName);
if (got != null) {
return got;
}
AmzaClientCallRouter<C, E> partitionCallRouter = new AmzaClientCallRouter<>(callerThreads, partitionHostsProvider, clientProvider);
return partitionClientFactory.create(partitionName, partitionCallRouter, awaitLeaderElectionForNMillis, debugClientCount, debugClientCountInterval);
}
@Override
public PartitionClient getPartition(PartitionName partitionName,
int ringSize,
PartitionProperties partitionProperties) throws Exception {
return cache.computeIfAbsent(partitionName, (key) -> {
try {
partitionHostsProvider.ensurePartition(partitionName, ringSize, partitionProperties);
AmzaClientCallRouter<C, E> partitionCallRouter = new AmzaClientCallRouter<>(callerThreads, partitionHostsProvider, clientProvider);
return partitionClientFactory.create(key, partitionCallRouter, awaitLeaderElectionForNMillis, debugClientCount, debugClientCountInterval);
} catch (Exception x) {
throw new RuntimeException(x);
}
});
}
@Override
public RingPartitionProperties getProperties(PartitionName partitionName) throws Exception {
return partitionHostsProvider.getRingPartitionProperties(partitionName);
}
}