use of com.palantir.atlasdb.keyvalue.cassandra.CassandraClientPoolingContainer in project atlasdb by palantir.
the class CassandraService method removePool.
/**
* Removes the pool from the set of current pools. Note that this shuts down all idle connections, but active ones
* remain alive until they are returned to the pool, whereby they are destroyed immediately. Threads waiting on the
* pool will be interrupted.
*/
public void removePool(InetSocketAddress removedServerAddress) {
blacklist.remove(removedServerAddress);
CassandraClientPoolingContainer removedContainer = currentPools.remove(removedServerAddress);
try {
removedContainer.shutdownPooling();
} catch (Exception e) {
log.warn("While removing a host ({}) from the pool, we were unable to gently cleanup resources.", SafeArg.of("removedServerAddress", CassandraLogHelper.host(removedServerAddress)), e);
}
}
use of com.palantir.atlasdb.keyvalue.cassandra.CassandraClientPoolingContainer in project atlasdb by palantir.
the class CassandraService method getRandomGoodHostForPredicate.
public Optional<CassandraClientPoolingContainer> getRandomGoodHostForPredicate(Predicate<InetSocketAddress> predicate, Set<InetSocketAddress> triedHosts) {
Map<InetSocketAddress, CassandraClientPoolingContainer> pools = currentPools;
Set<InetSocketAddress> hostsMatchingPredicate = pools.keySet().stream().filter(predicate).collect(Collectors.toSet());
Map<String, Long> triedDatacenters = triedHosts.stream().map(hostToDatacenter::get).filter(Objects::nonNull).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Optional<Long> maximumAttemptsPerDatacenter = triedDatacenters.values().stream().max(Long::compareTo);
Set<String> maximallyAttemptedDatacenters = KeyedStream.stream(triedDatacenters).filter(attempts -> Objects.equals(attempts, maximumAttemptsPerDatacenter.orElseThrow(() -> new SafeIllegalStateException("Unexpectedly could not find the max attempts per datacenter")))).keys().collect(Collectors.toSet());
Set<InetSocketAddress> hostsInPermittedDatacenters = hostsMatchingPredicate.stream().filter(pool -> {
String datacenter = hostToDatacenter.get(pool);
return datacenter == null || !maximallyAttemptedDatacenters.contains(datacenter);
}).collect(Collectors.toSet());
Set<InetSocketAddress> filteredHosts = hostsInPermittedDatacenters.isEmpty() ? hostsMatchingPredicate : hostsInPermittedDatacenters;
if (filteredHosts.isEmpty()) {
log.info("No hosts match the provided predicate.");
return Optional.empty();
}
Set<InetSocketAddress> livingHosts = blacklist.filterBlacklistedHostsFrom(filteredHosts);
if (livingHosts.isEmpty()) {
log.info("There are no known live hosts in the connection pool matching the predicate. We're choosing" + " one at random in a last-ditch attempt at forward progress.");
livingHosts = filteredHosts;
}
Optional<InetSocketAddress> randomLivingHost = getRandomHostByActiveConnections(livingHosts);
return randomLivingHost.map(pools::get);
}
use of com.palantir.atlasdb.keyvalue.cassandra.CassandraClientPoolingContainer in project atlasdb by palantir.
the class WeightedHostsTest method testSelectingHostFromWeightedHostsMatchesWeight.
// Covers a bug where we used ceilingEntry instead of higherEntry
@Test
public void testSelectingHostFromWeightedHostsMatchesWeight() {
Map<InetSocketAddress, CassandraClientPoolingContainer> pools = ImmutableMap.of(new InetSocketAddress(0), createMockClientPoolingContainerWithUtilization(5), new InetSocketAddress(1), createMockClientPoolingContainerWithUtilization(10), new InetSocketAddress(2), createMockClientPoolingContainerWithUtilization(15));
WeightedHosts weightedHosts = WeightedHosts.create(pools);
Map<InetSocketAddress, Integer> hostsToWeight = new HashMap<>();
int prevKey = 0;
for (Map.Entry<Integer, InetSocketAddress> entry : weightedHosts.hosts.entrySet()) {
hostsToWeight.put(entry.getValue(), entry.getKey() - prevKey);
prevKey = entry.getKey();
}
// Exhaustively test all indexes
Map<InetSocketAddress, Integer> numTimesSelected = new HashMap<>();
for (int index = 0; index < weightedHosts.hosts.lastKey(); index++) {
InetSocketAddress host = weightedHosts.getRandomHostInternal(index);
if (!numTimesSelected.containsKey(host)) {
numTimesSelected.put(host, 0);
}
numTimesSelected.put(host, numTimesSelected.get(host) + 1);
}
assertThat(numTimesSelected).containsExactlyInAnyOrderEntriesOf(hostsToWeight);
}
use of com.palantir.atlasdb.keyvalue.cassandra.CassandraClientPoolingContainer in project atlasdb by palantir.
the class WeightedHostsTest method testWeightedHostsWithUniformActivity.
@Test
public void testWeightedHostsWithUniformActivity() {
Map<InetSocketAddress, CassandraClientPoolingContainer> pools = ImmutableMap.of(new InetSocketAddress(0), createMockClientPoolingContainerWithUtilization(10), new InetSocketAddress(1), createMockClientPoolingContainerWithUtilization(10), new InetSocketAddress(2), createMockClientPoolingContainerWithUtilization(10));
NavigableMap<Integer, InetSocketAddress> result = WeightedHosts.create(pools).hosts;
int expectedWeight = result.firstEntry().getKey();
int prevKey = 0;
for (Map.Entry<Integer, InetSocketAddress> entry : result.entrySet()) {
int currWeight = entry.getKey() - prevKey;
assertThat(currWeight).isEqualTo(expectedWeight);
prevKey = entry.getKey();
}
}
use of com.palantir.atlasdb.keyvalue.cassandra.CassandraClientPoolingContainer in project atlasdb by palantir.
the class WeightedHostsTest method createMockClientPoolingContainerWithUtilization.
private static CassandraClientPoolingContainer createMockClientPoolingContainerWithUtilization(int utilization) {
CassandraClientPoolingContainer mock = Mockito.mock(CassandraClientPoolingContainer.class);
Mockito.when(mock.getOpenRequests()).thenReturn(utilization);
return mock;
}
Aggregations