Search in sources :

Example 1 with QueryResponse

use of io.atomix.protocols.raft.protocol.QueryResponse in project atomix by atomix.

the class RaftProxyInvokerTest method testSkippingOverFailedQuery.

/**
 * Tests skipping over a failed query attempt.
 */
@Test
public void testSkippingOverFailedQuery() throws Throwable {
    CompletableFuture<QueryResponse> future1 = new CompletableFuture<>();
    CompletableFuture<QueryResponse> future2 = new CompletableFuture<>();
    RaftProxyConnection connection = mock(RaftProxyConnection.class);
    Mockito.when(connection.query(any(QueryRequest.class))).thenReturn(future1).thenReturn(future2);
    RaftProxyState state = new RaftProxyState("test", SessionId.from(1), UUID.randomUUID().toString(), new TestPrimitiveType(), 1000);
    RaftProxyManager manager = mock(RaftProxyManager.class);
    ThreadContext threadContext = new TestContext();
    RaftProxyInvoker submitter = new RaftProxyInvoker(mock(RaftProxyConnection.class), connection, state, new RaftProxySequencer(state), manager, threadContext);
    CompletableFuture<byte[]> result1 = submitter.invoke(new PrimitiveOperation(QUERY, HeapBytes.EMPTY));
    CompletableFuture<byte[]> result2 = submitter.invoke(new PrimitiveOperation(QUERY, HeapBytes.EMPTY));
    assertEquals(state.getResponseIndex(), 1);
    assertFalse(result1.isDone());
    assertFalse(result2.isDone());
    future1.completeExceptionally(new RaftException.QueryFailure("failure"));
    future2.complete(QueryResponse.builder().withStatus(RaftResponse.Status.OK).withIndex(10).withResult("Hello world!".getBytes()).build());
    assertTrue(result1.isCompletedExceptionally());
    assertTrue(result2.isDone());
    assertTrue(Arrays.equals(result2.get(), "Hello world!".getBytes()));
    assertEquals(state.getResponseIndex(), 10);
}
Also used : PrimitiveOperation(io.atomix.primitive.operation.PrimitiveOperation) RaftException(io.atomix.protocols.raft.RaftException) ThreadContext(io.atomix.utils.concurrent.ThreadContext) CompletableFuture(java.util.concurrent.CompletableFuture) QueryResponse(io.atomix.protocols.raft.protocol.QueryResponse) Test(org.junit.Test)

Example 2 with QueryResponse

use of io.atomix.protocols.raft.protocol.QueryResponse in project atomix by atomix.

the class RaftProxySequencerTest method testSequenceResponses.

/**
 * Tests sequencing callbacks with the sequencer.
 */
@Test
public void testSequenceResponses() throws Throwable {
    RaftProxySequencer sequencer = new RaftProxySequencer(new RaftProxyState("test", SessionId.from(1), UUID.randomUUID().toString(), new TestPrimitiveType(), 1000));
    long sequence1 = sequencer.nextRequest();
    long sequence2 = sequencer.nextRequest();
    assertTrue(sequence2 == sequence1 + 1);
    CommandResponse commandResponse = CommandResponse.builder().withStatus(RaftResponse.Status.OK).withIndex(2).withEventIndex(0).build();
    QueryResponse queryResponse = QueryResponse.builder().withStatus(RaftResponse.Status.OK).withIndex(2).withEventIndex(0).build();
    AtomicBoolean run = new AtomicBoolean();
    sequencer.sequenceResponse(sequence2, queryResponse, () -> run.set(true));
    sequencer.sequenceResponse(sequence1, commandResponse, () -> assertFalse(run.get()));
    assertTrue(run.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) QueryResponse(io.atomix.protocols.raft.protocol.QueryResponse) CommandResponse(io.atomix.protocols.raft.protocol.CommandResponse) Test(org.junit.Test)

Example 3 with QueryResponse

use of io.atomix.protocols.raft.protocol.QueryResponse in project atomix by atomix.

the class LeaderRole method onQuery.

@Override
public CompletableFuture<QueryResponse> onQuery(final QueryRequest request) {
    raft.checkThread();
    logRequest(request);
    // doesn't exist if the follower hasn't had a chance to see the session's registration entry.
    if (raft.getLastApplied() < request.session()) {
        return CompletableFuture.completedFuture(logResponse(QueryResponse.builder().withStatus(RaftResponse.Status.ERROR).withError(RaftError.Type.UNKNOWN_SESSION, "Session has not yet been created. You're seeing into the future!").build()));
    }
    // Look up the client's session.
    RaftSession session = raft.getSessions().getSession(request.session());
    if (session == null) {
        log.warn("Unknown session {}", request.session());
        return CompletableFuture.completedFuture(logResponse(QueryResponse.builder().withStatus(RaftResponse.Status.ERROR).withError(RaftError.Type.UNKNOWN_SESSION).build()));
    }
    final Indexed<QueryEntry> entry = new Indexed<>(request.index(), new QueryEntry(raft.getTerm(), System.currentTimeMillis(), request.session(), request.sequenceNumber(), request.operation()), 0);
    final CompletableFuture<QueryResponse> future;
    switch(session.readConsistency()) {
        case SEQUENTIAL:
            future = queryLocal(entry);
            break;
        case LINEARIZABLE_LEASE:
            future = queryBoundedLinearizable(entry);
            break;
        case LINEARIZABLE:
            future = queryLinearizable(entry);
            break;
        default:
            future = Futures.exceptionalFuture(new IllegalStateException("Unknown consistency level: " + session.readConsistency()));
            break;
    }
    return future.thenApply(this::logResponse);
}
Also used : QueryEntry(io.atomix.protocols.raft.storage.log.entry.QueryEntry) RaftSession(io.atomix.protocols.raft.session.RaftSession) QueryResponse(io.atomix.protocols.raft.protocol.QueryResponse) Indexed(io.atomix.storage.journal.Indexed)

Example 4 with QueryResponse

use of io.atomix.protocols.raft.protocol.QueryResponse in project atomix by atomix.

the class RaftProxyInvokerTest method testExpireSessionOnQueryFailure.

/**
 * Tests that the client's session is expired when an UnknownSessionException is received from the cluster.
 */
@Test
public void testExpireSessionOnQueryFailure() throws Throwable {
    CompletableFuture<QueryResponse> future = new CompletableFuture<>();
    RaftProxyConnection connection = mock(RaftProxyConnection.class);
    Mockito.when(connection.query(any(QueryRequest.class))).thenReturn(future);
    RaftProxyState state = new RaftProxyState("test", SessionId.from(1), UUID.randomUUID().toString(), new TestPrimitiveType(), 1000);
    RaftProxyManager manager = mock(RaftProxyManager.class);
    ThreadContext threadContext = new TestContext();
    RaftProxyInvoker submitter = new RaftProxyInvoker(mock(RaftProxyConnection.class), connection, state, new RaftProxySequencer(state), manager, threadContext);
    CompletableFuture<byte[]> result = submitter.invoke(new PrimitiveOperation(QUERY, HeapBytes.EMPTY));
    assertEquals(state.getResponseIndex(), 1);
    assertFalse(result.isDone());
    future.completeExceptionally(new RaftException.UnknownSession("unknown session"));
    assertTrue(result.isCompletedExceptionally());
}
Also used : PrimitiveOperation(io.atomix.primitive.operation.PrimitiveOperation) RaftException(io.atomix.protocols.raft.RaftException) QueryRequest(io.atomix.protocols.raft.protocol.QueryRequest) ThreadContext(io.atomix.utils.concurrent.ThreadContext) CompletableFuture(java.util.concurrent.CompletableFuture) QueryResponse(io.atomix.protocols.raft.protocol.QueryResponse) Test(org.junit.Test)

Example 5 with QueryResponse

use of io.atomix.protocols.raft.protocol.QueryResponse in project atomix by atomix.

the class RaftProxyInvokerTest method testResequenceQuery.

/**
 * Tests resequencing a query response.
 */
@Test
public void testResequenceQuery() throws Throwable {
    CompletableFuture<QueryResponse> future1 = new CompletableFuture<>();
    CompletableFuture<QueryResponse> future2 = new CompletableFuture<>();
    RaftProxyConnection connection = mock(RaftProxyConnection.class);
    Mockito.when(connection.query(any(QueryRequest.class))).thenReturn(future1).thenReturn(future2);
    RaftProxyState state = new RaftProxyState("test", SessionId.from(1), UUID.randomUUID().toString(), new TestPrimitiveType(), 1000);
    RaftProxyManager manager = mock(RaftProxyManager.class);
    ThreadContext threadContext = new TestContext();
    RaftProxyInvoker submitter = new RaftProxyInvoker(mock(RaftProxyConnection.class), connection, state, new RaftProxySequencer(state), manager, threadContext);
    CompletableFuture<byte[]> result1 = submitter.invoke(new PrimitiveOperation(QUERY, HeapBytes.EMPTY));
    CompletableFuture<byte[]> result2 = submitter.invoke(new PrimitiveOperation(QUERY, HeapBytes.EMPTY));
    future2.complete(QueryResponse.builder().withStatus(RaftResponse.Status.OK).withIndex(10).withResult("Hello world again!".getBytes()).build());
    assertEquals(state.getResponseIndex(), 1);
    assertFalse(result1.isDone());
    assertFalse(result2.isDone());
    future1.complete(QueryResponse.builder().withStatus(RaftResponse.Status.OK).withIndex(9).withResult("Hello world!".getBytes()).build());
    assertTrue(result1.isDone());
    assertTrue(Arrays.equals(result1.get(), "Hello world!".getBytes()));
    assertTrue(result2.isDone());
    assertTrue(Arrays.equals(result2.get(), "Hello world again!".getBytes()));
    assertEquals(state.getResponseIndex(), 10);
}
Also used : PrimitiveOperation(io.atomix.primitive.operation.PrimitiveOperation) ThreadContext(io.atomix.utils.concurrent.ThreadContext) CompletableFuture(java.util.concurrent.CompletableFuture) QueryResponse(io.atomix.protocols.raft.protocol.QueryResponse) Test(org.junit.Test)

Aggregations

QueryResponse (io.atomix.protocols.raft.protocol.QueryResponse)5 Test (org.junit.Test)4 PrimitiveOperation (io.atomix.primitive.operation.PrimitiveOperation)3 ThreadContext (io.atomix.utils.concurrent.ThreadContext)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 RaftException (io.atomix.protocols.raft.RaftException)2 CommandResponse (io.atomix.protocols.raft.protocol.CommandResponse)1 QueryRequest (io.atomix.protocols.raft.protocol.QueryRequest)1 RaftSession (io.atomix.protocols.raft.session.RaftSession)1 QueryEntry (io.atomix.protocols.raft.storage.log.entry.QueryEntry)1 Indexed (io.atomix.storage.journal.Indexed)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1