Search in sources :

Example 1 with SessionClient

use of io.atomix.primitive.session.SessionClient in project atomix by atomix.

the class RaftFuzzTest method runFuzzTest.

/**
 * Runs a single fuzz test.
 */
private void runFuzzTest() throws Exception {
    reset();
    createServers(randomNumber(5) + 3);
    final Object lock = new Object();
    final AtomicLong index = new AtomicLong();
    final Map<Integer, Long> indexes = new HashMap<>();
    ThreadContext context = new SingleThreadContext("fuzz-test");
    int clients = randomNumber(10) + 1;
    for (int i = 0; i < clients; i++) {
        ReadConsistency consistency = randomConsistency();
        RaftClient client = createClient();
        SessionClient proxy = createProxy(client, consistency);
        Scheduler scheduler = new SingleThreadContext("fuzz-test-" + i);
        final int clientId = i;
        scheduler.schedule(Duration.ofMillis((100 * clients) + (randomNumber(50) - 25)), Duration.ofMillis((100 * clients) + (randomNumber(50) - 25)), () -> {
            long lastLinearizableIndex = index.get();
            int type = randomNumber(4);
            switch(type) {
                case 0:
                    proxy.execute(operation(PUT, CLIENT_SERIALIZER.encode(Maps.immutableEntry(randomKey(), randomString(1024 * 16))))).<Long>thenApply(CLIENT_SERIALIZER::decode).thenAccept(result -> {
                        synchronized (lock) {
                            if (result < lastLinearizableIndex) {
                                System.out.println(result + " is less than last linearizable index " + lastLinearizableIndex);
                                System.exit(1);
                            } else if (result > index.get()) {
                                index.set(result);
                            }
                            Long lastSequentialIndex = indexes.get(clientId);
                            if (lastSequentialIndex == null) {
                                indexes.put(clientId, result);
                            } else if (result < lastSequentialIndex) {
                                System.out.println(result + " is less than last sequential index " + lastSequentialIndex);
                                System.exit(1);
                            } else {
                                indexes.put(clientId, lastSequentialIndex);
                            }
                        }
                    });
                    break;
                case 1:
                    proxy.execute(operation(GET, CLIENT_SERIALIZER.encode(randomKey())));
                    break;
                case 2:
                    proxy.execute(operation(REMOVE, CLIENT_SERIALIZER.encode(randomKey()))).<Long>thenApply(CLIENT_SERIALIZER::decode).thenAccept(result -> {
                        synchronized (lock) {
                            if (result < lastLinearizableIndex) {
                                System.out.println(result + " is less than last linearizable index " + lastLinearizableIndex);
                                System.exit(1);
                            } else if (result > index.get()) {
                                index.set(result);
                            }
                            Long lastSequentialIndex = indexes.get(clientId);
                            if (lastSequentialIndex == null) {
                                indexes.put(clientId, result);
                            } else if (result < lastSequentialIndex) {
                                System.out.println(result + " is less than last sequential index " + lastSequentialIndex);
                                System.exit(1);
                            } else {
                                indexes.put(clientId, lastSequentialIndex);
                            }
                        }
                    });
                    break;
                case 3:
                    proxy.execute(operation(INDEX)).<Long>thenApply(CLIENT_SERIALIZER::decode).thenAccept(result -> {
                        synchronized (lock) {
                            switch(consistency) {
                                case LINEARIZABLE:
                                case LINEARIZABLE_LEASE:
                                    if (result < lastLinearizableIndex) {
                                        System.out.println(result + " is less than last linearizable index " + lastLinearizableIndex);
                                        System.exit(1);
                                    } else if (result > index.get()) {
                                        index.set(result);
                                    }
                                case SEQUENTIAL:
                                    Long lastSequentialIndex = indexes.get(clientId);
                                    if (lastSequentialIndex == null) {
                                        indexes.put(clientId, result);
                                    } else if (result < lastSequentialIndex) {
                                        System.out.println(result + " is less than last sequential index " + lastSequentialIndex);
                                        System.exit(1);
                                    } else {
                                        indexes.put(clientId, lastSequentialIndex);
                                    }
                            }
                        }
                    });
            }
        });
    }
    scheduleRestarts(context);
    Thread.sleep(Duration.ofMinutes(15).toMillis());
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) SessionClient(io.atomix.primitive.session.SessionClient) Scheduler(io.atomix.utils.concurrent.Scheduler) SingleThreadContext(io.atomix.utils.concurrent.SingleThreadContext) ThreadContext(io.atomix.utils.concurrent.ThreadContext) ReadConsistency(io.atomix.protocols.raft.ReadConsistency) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicLong(java.util.concurrent.atomic.AtomicLong) SingleThreadContext(io.atomix.utils.concurrent.SingleThreadContext) RaftClient(io.atomix.protocols.raft.RaftClient)

Example 2 with SessionClient

use of io.atomix.primitive.session.SessionClient in project atomix by atomix.

the class PrimaryBackupTest method testEvents.

/**
 * Tests submitting sequential events to all sessions.
 */
private void testEvents(int nodes, int backups, Replication replication) throws Throwable {
    createServers(nodes);
    PrimaryBackupClient client1 = createClient();
    SessionClient session1 = createProxy(client1, backups, replication);
    session1.addEventListener(CHANGE_EVENT, event -> {
        threadAssertNotNull(event);
        resume();
    });
    PrimaryBackupClient client2 = createClient();
    SessionClient session2 = createProxy(client2, backups, replication);
    session2.addEventListener(CHANGE_EVENT, event -> {
        threadAssertNotNull(event);
        resume();
    });
    session1.execute(operation(READ, null)).thenRun(this::resume);
    session2.execute(operation(READ, null)).thenRun(this::resume);
    await(5000, 2);
    session1.execute(operation(EVENT, SERIALIZER.encode(false))).thenRun(this::resume);
    await(5000, 3);
}
Also used : SessionClient(io.atomix.primitive.session.SessionClient)

Example 3 with SessionClient

use of io.atomix.primitive.session.SessionClient in project atomix by atomix.

the class DefaultRaftClient method sessionBuilder.

@Override
public RaftSessionClient.Builder sessionBuilder(String primitiveName, PrimitiveType primitiveType, ServiceConfig serviceConfig) {
    return new RaftSessionClient.Builder() {

        @Override
        public SessionClient build() {
            // Create a proxy builder that uses the session manager to open a session.
            Supplier<CompletableFuture<SessionClient>> proxyFactory = () -> CompletableFuture.completedFuture(new DefaultRaftSessionClient(primitiveName, primitiveType, serviceConfig, partitionId, DefaultRaftClient.this.protocol, selectorManager, sessionManager, readConsistency, communicationStrategy, threadContextFactory.createContext(), minTimeout, maxTimeout));
            SessionClient proxy;
            ThreadContext context = threadContextFactory.createContext();
            // If the recovery strategy is set to RECOVER, wrap the builder in a recovering proxy client.
            if (recoveryStrategy == Recovery.RECOVER) {
                proxy = new RecoveringSessionClient(clientId, partitionId, primitiveName, primitiveType, proxyFactory, context);
            } else {
                proxy = proxyFactory.get().join();
            }
            // If max retries is set, wrap the client in a retrying proxy client.
            if (maxRetries > 0) {
                proxy = new RetryingSessionClient(proxy, context, maxRetries, retryDelay);
            }
            return new BlockingAwareSessionClient(proxy, context);
        }
    };
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) RecoveringSessionClient(io.atomix.primitive.session.impl.RecoveringSessionClient) BlockingAwareSessionClient(io.atomix.primitive.session.impl.BlockingAwareSessionClient) RaftSessionClient(io.atomix.protocols.raft.session.RaftSessionClient) BlockingAwareSessionClient(io.atomix.primitive.session.impl.BlockingAwareSessionClient) RetryingSessionClient(io.atomix.primitive.session.impl.RetryingSessionClient) DefaultRaftSessionClient(io.atomix.protocols.raft.session.impl.DefaultRaftSessionClient) RecoveringSessionClient(io.atomix.primitive.session.impl.RecoveringSessionClient) SessionClient(io.atomix.primitive.session.SessionClient) ThreadContext(io.atomix.utils.concurrent.ThreadContext) DefaultRaftSessionClient(io.atomix.protocols.raft.session.impl.DefaultRaftSessionClient) RetryingSessionClient(io.atomix.primitive.session.impl.RetryingSessionClient)

Example 4 with SessionClient

use of io.atomix.primitive.session.SessionClient in project atomix by atomix.

the class PrimaryBackupTest method testSequentialEvent.

/**
 * Tests submitting a sequential event.
 */
private void testSequentialEvent(int nodes, int backups, Replication replication) throws Throwable {
    createServers(nodes);
    AtomicLong count = new AtomicLong();
    AtomicLong index = new AtomicLong();
    PrimaryBackupClient client = createClient();
    SessionClient session = createProxy(client, backups, replication);
    session.<Long>addEventListener(CHANGE_EVENT, event -> {
        threadAssertEquals(count.incrementAndGet(), 2L);
        threadAssertEquals(index.get(), SERIALIZER.decode(event.value()));
        resume();
    });
    session.execute(operation(EVENT, SERIALIZER.encode(true))).<Long>thenApply(SERIALIZER::decode).thenAccept(result -> {
        threadAssertNotNull(result);
        threadAssertEquals(count.incrementAndGet(), 1L);
        index.set(result);
        resume();
    });
    await(5000, 2);
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) SessionClient(io.atomix.primitive.session.SessionClient) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 5 with SessionClient

use of io.atomix.primitive.session.SessionClient in project atomix by atomix.

the class PrimaryBackupTest method testManyEventsAfterPrimaryShutdown.

/**
 * Tests events after a primary shutdown.
 */
private void testManyEventsAfterPrimaryShutdown(Replication replication) throws Throwable {
    List<PrimaryBackupServer> servers = createServers(5);
    PrimaryBackupClient client = createClient();
    SessionClient session = createProxy(client, 3, replication);
    session.addEventListener(CHANGE_EVENT, event -> {
        threadAssertNotNull(event);
        resume();
    });
    for (int i = 0; i < 10; i++) {
        session.execute(operation(EVENT, SERIALIZER.encode(true))).thenRun(this::resume);
        await(5000, 2);
    }
    PrimaryBackupServer leader = servers.stream().filter(s -> s.getRole() == Role.PRIMARY).findFirst().get();
    leader.stop().get(10, TimeUnit.SECONDS);
    for (int i = 0; i < 10; i++) {
        session.execute(operation(EVENT, SERIALIZER.encode(true))).thenRun(this::resume);
        await(5000, 2);
    }
}
Also used : SessionClient(io.atomix.primitive.session.SessionClient)

Aggregations

SessionClient (io.atomix.primitive.session.SessionClient)19 PrimitiveType (io.atomix.primitive.PrimitiveType)3 DefaultProxyClient (io.atomix.primitive.proxy.impl.DefaultProxyClient)3 ThreadContext (io.atomix.utils.concurrent.ThreadContext)3 PartitionGroup (io.atomix.primitive.partition.PartitionGroup)2 PartitionService (io.atomix.primitive.partition.PartitionService)2 PrimitiveProtocol (io.atomix.primitive.protocol.PrimitiveProtocol)2 ProxyProtocol (io.atomix.primitive.protocol.ProxyProtocol)2 ProxyClient (io.atomix.primitive.proxy.ProxyClient)2 ServiceConfig (io.atomix.primitive.service.ServiceConfig)2 BlockingAwareSessionClient (io.atomix.primitive.session.impl.BlockingAwareSessionClient)2 RecoveringSessionClient (io.atomix.primitive.session.impl.RecoveringSessionClient)2 RetryingSessionClient (io.atomix.primitive.session.impl.RetryingSessionClient)2 ConfigurationException (io.atomix.utils.config.ConfigurationException)2 Collection (java.util.Collection)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 Collectors (java.util.stream.Collectors)2 MoreObjects.toStringHelper (com.google.common.base.MoreObjects.toStringHelper)1 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1