Search in sources :

Example 6 with PingableLeader

use of com.palantir.leader.PingableLeader in project atlasdb by palantir.

the class TransactionManagers method createRawLeaderServices.

private static LockAndTimestampServices createRawLeaderServices(LeaderConfig leaderConfig, Consumer<Object> env, com.google.common.base.Supplier<LockService> lock, com.google.common.base.Supplier<TimestampService> time, String userAgent) {
    // Create local services, that may or may not end up being registered in an Consumer<Object>.
    LeaderRuntimeConfig defaultRuntime = ImmutableLeaderRuntimeConfig.builder().build();
    LocalPaxosServices localPaxosServices = Leaders.createAndRegisterLocalServices(env, leaderConfig, () -> defaultRuntime, userAgent);
    LeaderElectionService leader = localPaxosServices.leaderElectionService();
    LockService localLock = ServiceCreator.createInstrumentedService(AwaitingLeadershipProxy.newProxyInstance(LockService.class, lock, leader), LockService.class);
    TimestampService localTime = ServiceCreator.createInstrumentedService(AwaitingLeadershipProxy.newProxyInstance(TimestampService.class, time, leader), TimestampService.class);
    env.accept(localLock);
    env.accept(localTime);
    // Create remote services, that may end up calling our own local services.
    ImmutableServerListConfig serverListConfig = ImmutableServerListConfig.builder().servers(leaderConfig.leaders()).sslConfiguration(leaderConfig.sslConfiguration()).build();
    LockService remoteLock = new ServiceCreator<>(LockService.class, userAgent).apply(serverListConfig);
    TimestampService remoteTime = new ServiceCreator<>(TimestampService.class, userAgent).apply(serverListConfig);
    if (leaderConfig.leaders().size() == 1) {
        // Attempting to connect to ourself while processing a request can lead to deadlock if incoming request
        // volume is high, as all Jetty threads end up waiting for the timestamp server, and no threads remain to
        // actually handle the timestamp server requests. If we are the only single leader, we can avoid the
        // deadlock entirely; so use PingableLeader's getUUID() to detect this situation and eliminate the redundant
        // call.
        PingableLeader localPingableLeader = localPaxosServices.pingableLeader();
        String localServerId = localPingableLeader.getUUID();
        PingableLeader remotePingableLeader = AtlasDbFeignTargetFactory.createRsProxy(ServiceCreator.createSslSocketFactory(leaderConfig.sslConfiguration()), Iterables.getOnlyElement(leaderConfig.leaders()), PingableLeader.class, userAgent);
        // Determine asynchronously whether the remote services are talking to our local services.
        CompletableFuture<Boolean> useLocalServicesFuture = new CompletableFuture<>();
        runAsync.accept(() -> {
            int logAfter = LOGGING_INTERVAL;
            while (true) {
                try {
                    String remoteServerId = remotePingableLeader.getUUID();
                    useLocalServicesFuture.complete(localServerId.equals(remoteServerId));
                    return;
                } catch (ClientErrorException e) {
                    useLocalServicesFuture.complete(false);
                    return;
                } catch (Throwable e) {
                    if (--logAfter == 0) {
                        log.warn("Failed to read remote timestamp server ID", e);
                        logAfter = LOGGING_INTERVAL;
                    }
                }
                Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
            }
        });
        // Create dynamic service proxies, that switch to talking directly to our local services if it turns out our
        // remote services are pointed at them anyway.
        LockService dynamicLockService = LocalOrRemoteProxy.newProxyInstance(LockService.class, localLock, remoteLock, useLocalServicesFuture);
        TimestampService dynamicTimeService = LocalOrRemoteProxy.newProxyInstance(TimestampService.class, localTime, remoteTime, useLocalServicesFuture);
        return ImmutableLockAndTimestampServices.builder().lock(dynamicLockService).timestamp(dynamicTimeService).timelock(new LegacyTimelockService(dynamicTimeService, dynamicLockService, LOCK_CLIENT)).build();
    } else {
        return ImmutableLockAndTimestampServices.builder().lock(remoteLock).timestamp(remoteTime).timelock(new LegacyTimelockService(remoteTime, remoteLock, LOCK_CLIENT)).build();
    }
}
Also used : LegacyTimelockService(com.palantir.lock.impl.LegacyTimelockService) ImmutableServerListConfig(com.palantir.atlasdb.config.ImmutableServerListConfig) NoOpPersistentLockService(com.palantir.atlasdb.persistentlock.NoOpPersistentLockService) KvsBackedPersistentLockService(com.palantir.atlasdb.persistentlock.KvsBackedPersistentLockService) LockService(com.palantir.lock.LockService) LockRefreshingLockService(com.palantir.lock.client.LockRefreshingLockService) PersistentLockService(com.palantir.atlasdb.persistentlock.PersistentLockService) LocalPaxosServices(com.palantir.atlasdb.factory.Leaders.LocalPaxosServices) CompletableFuture(java.util.concurrent.CompletableFuture) PingableLeader(com.palantir.leader.PingableLeader) LeaderElectionService(com.palantir.leader.LeaderElectionService) ClientErrorException(javax.ws.rs.ClientErrorException) LeaderRuntimeConfig(com.palantir.atlasdb.config.LeaderRuntimeConfig) ImmutableLeaderRuntimeConfig(com.palantir.atlasdb.config.ImmutableLeaderRuntimeConfig) TimestampService(com.palantir.timestamp.TimestampService)

Example 7 with PingableLeader

use of com.palantir.leader.PingableLeader in project atlasdb by palantir.

the class TransactionManagersTest method setUpForLocalServices.

private void setUpForLocalServices() throws IOException {
    doAnswer(invocation -> {
        // Configure our server to reply with the same server ID as the registered PingableLeader.
        PingableLeader localPingableLeader = invocation.getArgumentAt(0, PingableLeader.class);
        availableServer.stubFor(LEADER_UUID_MAPPING.willReturn(aResponse().withStatus(200).withBody(("\"" + localPingableLeader.getUUID().toString() + "\"").getBytes())));
        return null;
    }).when(environment).accept(isA(PingableLeader.class));
    setUpLeaderBlockInConfig();
}
Also used : PingableLeader(com.palantir.leader.PingableLeader)

Example 8 with PingableLeader

use of com.palantir.leader.PingableLeader in project atlasdb by palantir.

the class Leaders method generatePingables.

public static Map<PingableLeader, HostAndPort> generatePingables(Collection<String> remoteEndpoints, Optional<SSLSocketFactory> sslSocketFactory, String userAgent) {
    /* The interface used as a key here may be a proxy, which may have strange .equals() behavior.
         * This is circumvented by using an IdentityHashMap which will just use native == for equality.
         */
    Map<PingableLeader, HostAndPort> pingables = new IdentityHashMap<>();
    for (String endpoint : remoteEndpoints) {
        PingableLeader remoteInterface = AtlasDbHttpClients.createProxy(sslSocketFactory, endpoint, true, PingableLeader.class, userAgent);
        HostAndPort hostAndPort = HostAndPort.fromString(endpoint);
        pingables.put(remoteInterface, hostAndPort);
    }
    return pingables;
}
Also used : HostAndPort(com.google.common.net.HostAndPort) IdentityHashMap(java.util.IdentityHashMap) PingableLeader(com.palantir.leader.PingableLeader)

Example 9 with PingableLeader

use of com.palantir.leader.PingableLeader in project atlasdb by palantir.

the class LeaderRemotingTest method testPing.

@Test
public void testPing() {
    PingableLeader ping = AtlasDbFeignTargetFactory.createProxy(Optional.empty(), pingable.baseUri().toString(), PingableLeader.class, UserAgents.DEFAULT_USER_AGENT);
    ping.getUUID();
    ping.ping();
}
Also used : PingableLeader(com.palantir.leader.PingableLeader) Test(org.junit.Test)

Example 10 with PingableLeader

use of com.palantir.leader.PingableLeader in project atlasdb by palantir.

the class LeaderPingHealthCheckTest method getMockOfPingableLeaderWherePingReturns.

private PingableLeader getMockOfPingableLeaderWherePingReturns(boolean pingResult) {
    PingableLeader mockLeader = mock(PingableLeader.class);
    when(mockLeader.ping()).thenReturn(pingResult);
    return mockLeader;
}
Also used : PingableLeader(com.palantir.leader.PingableLeader)

Aggregations

PingableLeader (com.palantir.leader.PingableLeader)13 Test (org.junit.Test)5 HostAndPort (com.google.common.net.HostAndPort)2 LeaderRuntimeConfig (com.palantir.atlasdb.config.LeaderRuntimeConfig)2 LeaderElectionService (com.palantir.leader.LeaderElectionService)2 InstrumentedExecutorService (com.codahale.metrics.InstrumentedExecutorService)1 ThreadFactoryBuilder (com.google.common.util.concurrent.ThreadFactoryBuilder)1 ImmutableLeaderRuntimeConfig (com.palantir.atlasdb.config.ImmutableLeaderRuntimeConfig)1 ImmutableServerListConfig (com.palantir.atlasdb.config.ImmutableServerListConfig)1 LocalPaxosServices (com.palantir.atlasdb.factory.Leaders.LocalPaxosServices)1 AtlasDbRemoteException (com.palantir.atlasdb.http.errors.AtlasDbRemoteException)1 KvsBackedPersistentLockService (com.palantir.atlasdb.persistentlock.KvsBackedPersistentLockService)1 NoOpPersistentLockService (com.palantir.atlasdb.persistentlock.NoOpPersistentLockService)1 PersistentLockService (com.palantir.atlasdb.persistentlock.PersistentLockService)1 PaxosLeaderElectionService (com.palantir.leader.PaxosLeaderElectionService)1 PaxosLeaderElectionServiceBuilder (com.palantir.leader.PaxosLeaderElectionServiceBuilder)1 PaxosLeadershipEventRecorder (com.palantir.leader.PaxosLeadershipEventRecorder)1 LockService (com.palantir.lock.LockService)1 LockRefreshingLockService (com.palantir.lock.client.LockRefreshingLockService)1 LegacyTimelockService (com.palantir.lock.impl.LegacyTimelockService)1