use of com.palantir.logsafe.exceptions.SafeIllegalStateException 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.logsafe.exceptions.SafeIllegalStateException in project atlasdb by palantir.
the class TransactionServices method createReadOnlyTransactionServiceIgnoresUncommittedTransactionsDoesNotRollBack.
public static TransactionService createReadOnlyTransactionServiceIgnoresUncommittedTransactionsDoesNotRollBack(KeyValueService keyValueService, MetricsManager metricsManager) {
if (keyValueService.supportsCheckAndSet()) {
CoordinationService<InternalSchemaMetadata> coordinationService = CoordinationServices.createDefault(keyValueService, () -> {
throw new SafeIllegalStateException("Attempted to get a timestamp from a read-only" + " transaction service! This is probably a product bug. Please contact" + " support.");
}, metricsManager, false);
ReadOnlyTransactionSchemaManager readOnlyTransactionSchemaManager = new ReadOnlyTransactionSchemaManager(coordinationService);
return new PreStartHandlingTransactionService(new SplitKeyDelegatingTransactionService<>(readOnlyTransactionSchemaManager::getTransactionsSchemaVersion, ImmutableMap.of(1, createV1TransactionService(keyValueService))));
}
return createV1TransactionService(keyValueService);
}
use of com.palantir.logsafe.exceptions.SafeIllegalStateException in project atlasdb by palantir.
the class PaxosTimestampBoundStore method storeUpperLimit.
/**
* Proposes a new timestamp limit, with sequence number 1 greater than the current agreed bound, or
* PaxosAcceptor.NO_LOG_ENTRY + 1 if nothing has been proposed or accepted yet.
*
* @param limit the new upper limit to be stored
* @throws IllegalArgumentException if trying to persist a limit smaller than the agreed limit
* @throws NotCurrentLeaderException if the timestamp limit has changed out from under us
*/
@Override
public synchronized void storeUpperLimit(long limit) throws MultipleRunningTimestampServiceError {
long newSeq = PaxosAcceptor.NO_LOG_ENTRY + 1;
if (agreedState != null) {
Preconditions.checkArgument(limit >= agreedState.getBound(), "Tried to store an upper limit %s less than the current limit %s", limit, agreedState.getBound());
newSeq = agreedState.getSeqId() + 1;
}
while (true) {
try {
proposer.propose(newSeq, PtBytes.toBytes(limit));
PaxosValue value = knowledge.getLearnedValue(newSeq).orElseThrow(() -> new SafeIllegalStateException("Timestamp bound store: Paxos proposal" + " returned without learning a value. This is unexpected and would suggest a bug in" + " AtlasDB code. Please contact support."));
checkAgreedBoundIsOurs(limit, newSeq, value);
long newLimit = PtBytes.toLong(value.getData());
agreedState = ImmutableSequenceAndBound.of(newSeq, newLimit);
if (newLimit < limit) {
// The bound is ours, but is not high enough.
// This is dangerous; proposing at the next sequence number is unsafe, as timestamp services
// generally assume they have the ALLOCATION_BUFFER_SIZE timestamps up to this.
// TODO (jkong): Devise a method that better preserves availability of the cluster.
log.warn("It appears we updated the timestamp limit to {}, which was less than our target {}." + " This suggests we have another timestamp service running; possibly because we" + " lost and regained leadership. For safety, we are now stopping this service.", SafeArg.of("newLimit", newLimit), SafeArg.of("target", limit));
throw new NotCurrentLeaderException(String.format("We updated the timestamp limit to %s, which was less than our target %s.", newLimit, limit));
}
return;
} catch (PaxosRoundFailureException e) {
waitForRandomBackoff(e, this::wait);
}
}
}
use of com.palantir.logsafe.exceptions.SafeIllegalStateException in project atlasdb by palantir.
the class AtlasRestoreService method prepareRestore.
/**
* Disables TimeLock on all nodes for the given atlasServices.
* This will fail if any atlasService is already disabled, unless it was disabled with the provided backupId.
* AtlasServices for which we don't have a recorded backup will be ignored.
*
* @param restoreRequests the requests to prepare.
* @param backupId a unique identifier for this request (uniquely identifies the backup to which we're restoring)
*
* @return the atlasServices successfully disabled.
*/
public Set<AtlasService> prepareRestore(Set<RestoreRequest> restoreRequests, String backupId) {
validateRestoreRequests(restoreRequests);
Map<RestoreRequest, CompletedBackup> completedBackups = getCompletedBackups(restoreRequests);
Set<AtlasService> atlasServicesToRestore = getAtlasServicesToRestore(completedBackups);
Preconditions.checkArgument(atlasServicesToRestore.size() == completedBackups.size(), "Attempting to restore multiple atlasServices into the same atlasService! " + "This will cause severe data corruption.", SafeArg.of("restoreRequests", restoreRequests));
Set<Namespace> namespacesToRestore = atlasServicesToRestore.stream().map(AtlasService::getNamespace).collect(Collectors.toSet());
DisableNamespacesRequest request = DisableNamespacesRequest.of(namespacesToRestore, backupId);
DisableNamespacesResponse response = timeLockManagementService.disableTimelock(authHeader, request);
return response.accept(new DisableNamespacesResponse.Visitor<>() {
@Override
public Set<AtlasService> visitSuccessful(SuccessfulDisableNamespacesResponse value) {
return atlasServicesToRestore;
}
@Override
public Set<AtlasService> visitUnsuccessful(UnsuccessfulDisableNamespacesResponse value) {
log.error("Failed to disable namespaces prior to restore", SafeArg.of("requests", restoreRequests), SafeArg.of("response", value));
return ImmutableSet.of();
}
@Override
public Set<AtlasService> visitUnknown(String unknownType) {
throw new SafeIllegalStateException("Unknown DisableNamespacesResponse", SafeArg.of("unknownType", unknownType));
}
});
}
use of com.palantir.logsafe.exceptions.SafeIllegalStateException in project atlasdb by palantir.
the class MetricsBasedTimelockHealthCheck method getStatus.
@Override
public TimelockServiceStatus getStatus() {
Map<MetricName, Metric> metrics = metricsManager.getTaggedRegistry().getMetrics();
Metric success = metrics.get(MetricName.builder().safeName(AtlasDbMetricNames.TIMELOCK_SUCCESSFUL_REQUEST).build());
Metric failure = metrics.get(MetricName.builder().safeName(AtlasDbMetricNames.TIMELOCK_FAILED_REQUEST).build());
if (!(success instanceof Meter) || !(failure instanceof Meter)) {
throw new SafeIllegalStateException("Timelock client metrics is not properly set");
}
double successfulRequestRate = ((Meter) success).getFiveMinuteRate();
double failedRequestRate = ((Meter) failure).getFiveMinuteRate();
if (successfulRequestRate >= failedRequestRate) {
return TimelockServiceStatus.HEALTHY;
} else {
return TimelockServiceStatus.UNHEALTHY;
}
}
Aggregations