Search in sources :

Example 11 with PrimitiveProxy

use of io.atomix.primitive.proxy.PrimitiveProxy 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();
        PrimitiveProxy 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.<Map.Entry<String, String>, Long>invoke(PUT, clientSerializer::encode, Maps.immutableEntry(randomKey(), randomString(1024 * 16)), clientSerializer::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.invoke(GET, clientSerializer::encode, randomKey(), clientSerializer::decode);
                    break;
                case 2:
                    proxy.<String, Long>invoke(REMOVE, clientSerializer::encode, randomKey(), clientSerializer::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.<Long>invoke(INDEX, clientSerializer::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) Scheduler(io.atomix.utils.concurrent.Scheduler) SingleThreadContext(io.atomix.utils.concurrent.SingleThreadContext) ThreadContext(io.atomix.utils.concurrent.ThreadContext) Endpoint(io.atomix.messaging.Endpoint) PrimitiveProxy(io.atomix.primitive.proxy.PrimitiveProxy) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicLong(java.util.concurrent.atomic.AtomicLong) SingleThreadContext(io.atomix.utils.concurrent.SingleThreadContext) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 12 with PrimitiveProxy

use of io.atomix.primitive.proxy.PrimitiveProxy 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();
    PrimitiveProxy session = createProxy(client, backups, replication);
    session.<Long>addEventListener(CHANGE_EVENT, SERIALIZER::decode, event -> {
        threadAssertEquals(count.incrementAndGet(), 2L);
        threadAssertEquals(index.get(), event);
        resume();
    });
    session.<Boolean, Long>invoke(EVENT, SERIALIZER::encode, true, SERIALIZER::decode).thenAccept(result -> {
        threadAssertNotNull(result);
        threadAssertEquals(count.incrementAndGet(), 1L);
        index.set(result);
        resume();
    });
    await(5000, 2);
}
Also used : PrimitiveProxy(io.atomix.primitive.proxy.PrimitiveProxy) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 13 with PrimitiveProxy

use of io.atomix.primitive.proxy.PrimitiveProxy 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();
    PrimitiveProxy session1 = createProxy(client1, backups, replication);
    session1.addEventListener(event -> {
        threadAssertNotNull(event);
        resume();
    });
    PrimaryBackupClient client2 = createClient();
    PrimitiveProxy session2 = createProxy(client2, backups, replication);
    session2.addEventListener(event -> {
        threadAssertNotNull(event);
        resume();
    });
    session1.invoke(READ).thenRun(this::resume);
    session2.invoke(READ).thenRun(this::resume);
    await(5000, 2);
    session1.invoke(EVENT, SERIALIZER::encode, false).thenRun(this::resume);
    await(5000, 3);
}
Also used : PrimitiveProxy(io.atomix.primitive.proxy.PrimitiveProxy)

Example 14 with PrimitiveProxy

use of io.atomix.primitive.proxy.PrimitiveProxy 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();
    PrimitiveProxy session = createProxy(client, 3, replication);
    session.addEventListener(event -> {
        threadAssertNotNull(event);
        resume();
    });
    for (int i = 0; i < 10; i++) {
        session.invoke(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.invoke(EVENT, SERIALIZER::encode, true).thenRun(this::resume);
        await(5000, 2);
    }
}
Also used : PrimitiveProxy(io.atomix.primitive.proxy.PrimitiveProxy)

Example 15 with PrimitiveProxy

use of io.atomix.primitive.proxy.PrimitiveProxy in project atomix by atomix.

the class DefaultRaftClient method newProxy.

@Override
public PrimitiveProxy newProxy(String primitiveName, PrimitiveType primitiveType, RaftProtocol primitiveProtocol) {
    // Create a proxy builder that uses the session manager to open a session.
    Supplier<PrimitiveProxy> proxyFactory = () -> new DefaultRaftProxy(primitiveName, primitiveType, DefaultRaftClient.this.protocol, selectorManager, sessionManager, primitiveProtocol.readConsistency(), primitiveProtocol.communicationStrategy(), threadContextFactory.createContext(), primitiveProtocol.minTimeout(), primitiveProtocol.maxTimeout());
    PrimitiveProxy proxy;
    // If the recovery strategy is set to RECOVER, wrap the builder in a recovering proxy client.
    if (primitiveProtocol.recoveryStrategy() == Recovery.RECOVER) {
        proxy = new RecoveringPrimitiveProxy(clientId, primitiveName, primitiveType, proxyFactory, threadContextFactory.createContext());
    } else {
        proxy = proxyFactory.get();
    }
    // If max retries is set, wrap the client in a retrying proxy client.
    if (primitiveProtocol.maxRetries() > 0) {
        proxy = new RetryingPrimitiveProxy(proxy, threadContextFactory.createContext(), primitiveProtocol.maxRetries(), primitiveProtocol.retryDelay());
    }
    // Default the executor to use the configured thread pool executor and create a blocking aware proxy client.
    Executor executor = primitiveProtocol.executor() != null ? primitiveProtocol.executor() : threadContextFactory.createContext();
    return new BlockingAwarePrimitiveProxy(proxy, executor);
}
Also used : BlockingAwarePrimitiveProxy(io.atomix.primitive.proxy.impl.BlockingAwarePrimitiveProxy) RetryingPrimitiveProxy(io.atomix.primitive.proxy.impl.RetryingPrimitiveProxy) RecoveringPrimitiveProxy(io.atomix.primitive.proxy.impl.RecoveringPrimitiveProxy) PrimitiveProxy(io.atomix.primitive.proxy.PrimitiveProxy) Executor(java.util.concurrent.Executor) BlockingAwarePrimitiveProxy(io.atomix.primitive.proxy.impl.BlockingAwarePrimitiveProxy) RecoveringPrimitiveProxy(io.atomix.primitive.proxy.impl.RecoveringPrimitiveProxy) RetryingPrimitiveProxy(io.atomix.primitive.proxy.impl.RetryingPrimitiveProxy) DefaultRaftProxy(io.atomix.protocols.raft.proxy.impl.DefaultRaftProxy)

Aggregations

PrimitiveProxy (io.atomix.primitive.proxy.PrimitiveProxy)35 AtomicLong (java.util.concurrent.atomic.AtomicLong)5 Test (org.junit.Test)4 Endpoint (io.atomix.messaging.Endpoint)2 BlockingAwarePrimitiveProxy (io.atomix.primitive.proxy.impl.BlockingAwarePrimitiveProxy)2 RecoveringPrimitiveProxy (io.atomix.primitive.proxy.impl.RecoveringPrimitiveProxy)2 RetryingPrimitiveProxy (io.atomix.primitive.proxy.impl.RetryingPrimitiveProxy)2 Executor (java.util.concurrent.Executor)2 AtomicCounterProxy (io.atomix.core.counter.impl.AtomicCounterProxy)1 PrimitiveDescriptor (io.atomix.protocols.backup.protocol.PrimitiveDescriptor)1 PrimaryBackupProxy (io.atomix.protocols.backup.proxy.PrimaryBackupProxy)1 DefaultRaftProxy (io.atomix.protocols.raft.proxy.impl.DefaultRaftProxy)1 Scheduler (io.atomix.utils.concurrent.Scheduler)1 SingleThreadContext (io.atomix.utils.concurrent.SingleThreadContext)1 ThreadContext (io.atomix.utils.concurrent.ThreadContext)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ExecutionException (java.util.concurrent.ExecutionException)1