Search in sources :

Example 1 with Message

use of org.apache.ratis.protocol.Message in project incubator-ratis by apache.

the class StateMachineUpdater method run.

@Override
public void run() {
    final RaftStorage storage = server.getState().getStorage();
    while (isRunning()) {
        try {
            synchronized (this) {
                // Thus initially lastAppliedIndex can be greater than lastCommitted.
                while (lastAppliedIndex >= raftLog.getLastCommittedIndex()) {
                    wait();
                }
            }
            final long committedIndex = raftLog.getLastCommittedIndex();
            Preconditions.assertTrue(lastAppliedIndex < committedIndex);
            if (state == State.RELOAD) {
                Preconditions.assertTrue(stateMachine.getLifeCycleState() == LifeCycle.State.PAUSED);
                stateMachine.reinitialize(server.getId(), properties, storage);
                SnapshotInfo snapshot = stateMachine.getLatestSnapshot();
                Preconditions.assertTrue(snapshot != null && snapshot.getIndex() > lastAppliedIndex, "Snapshot: %s, lastAppliedIndex: %s", snapshot, lastAppliedIndex);
                lastAppliedIndex = snapshot.getIndex();
                lastSnapshotIndex = snapshot.getIndex();
                state = State.RUNNING;
            }
            final MemoizedSupplier<List<CompletableFuture<Message>>> futures = MemoizedSupplier.valueOf(() -> new ArrayList<>());
            while (lastAppliedIndex < committedIndex) {
                final long nextIndex = lastAppliedIndex + 1;
                final LogEntryProto next = raftLog.get(nextIndex);
                if (next != null) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("{}: applying nextIndex={}, nextLog={}", this, nextIndex, ServerProtoUtils.toString(next));
                    }
                    final CompletableFuture<Message> f = server.applyLogToStateMachine(next);
                    if (f != null) {
                        futures.get().add(f);
                    }
                    lastAppliedIndex = nextIndex;
                } else {
                    LOG.debug("{}: logEntry {} is null. There may be snapshot to load. state:{}", this, nextIndex, state);
                    break;
                }
            }
            // check if need to trigger a snapshot
            if (shouldTakeSnapshot(lastAppliedIndex)) {
                if (futures.isInitialized()) {
                    JavaUtils.allOf(futures.get()).get();
                }
                stateMachine.takeSnapshot();
                // TODO purge logs, including log cache. but should keep log for leader's RPCSenders
                lastSnapshotIndex = lastAppliedIndex;
            }
        } catch (InterruptedException e) {
            if (!isRunning()) {
                LOG.info("{}: the StateMachineUpdater is interrupted and will exit.", this);
            } else {
                final String s = this + ": the StateMachineUpdater is wrongly interrupted";
                ExitUtils.terminate(1, s, e, LOG);
            }
        } catch (Throwable t) {
            final String s = this + ": the StateMachineUpdater hits Throwable";
            ExitUtils.terminate(2, s, t, LOG);
        }
    }
}
Also used : SnapshotInfo(org.apache.ratis.statemachine.SnapshotInfo) LogEntryProto(org.apache.ratis.shaded.proto.RaftProtos.LogEntryProto) RaftStorage(org.apache.ratis.server.storage.RaftStorage) Message(org.apache.ratis.protocol.Message) ArrayList(java.util.ArrayList) List(java.util.List)

Example 2 with Message

use of org.apache.ratis.protocol.Message in project alluxio by Alluxio.

the class RaftJournalWriter method flush.

@Override
public void flush() throws IOException, JournalClosedException {
    if (mClosed) {
        throw new JournalClosedException("Cannot flush. Journal writer has been closed");
    }
    if (mJournalEntryBuilder != null) {
        long flushSN = mNextSequenceNumberToWrite.get() - 1;
        try {
            // It is ok to submit the same entries multiple times because we de-duplicate by sequence
            // number when applying them. This could happen if submit fails and we re-submit the same
            // entry on retry.
            JournalEntry entry = mJournalEntryBuilder.build();
            Message message = RaftJournalSystem.toRaftMessage(entry);
            mLastSubmittedSequenceNumber.set(flushSN);
            LOG.trace("Flushing entry {} ({})", entry, message);
            RaftClientReply reply = mClient.sendAsync(message, TimeDuration.valueOf(mWriteTimeoutMs, TimeUnit.MILLISECONDS)).get(mWriteTimeoutMs, TimeUnit.MILLISECONDS);
            mLastCommittedSequenceNumber.set(flushSN);
            if (reply.getException() != null) {
                throw reply.getException();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException(e);
        } catch (ExecutionException e) {
            throw new IOException(e.getCause());
        } catch (TimeoutException e) {
            throw new IOException(String.format("Timed out after waiting %s milliseconds for journal entries to be processed", mWriteTimeoutMs), e);
        }
        mJournalEntryBuilder = null;
    }
}
Also used : JournalClosedException(alluxio.exception.JournalClosedException) Message(org.apache.ratis.protocol.Message) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) JournalEntry(alluxio.proto.journal.Journal.JournalEntry) TimeoutException(java.util.concurrent.TimeoutException)

Example 3 with Message

use of org.apache.ratis.protocol.Message in project alluxio by Alluxio.

the class JournalStateMachine method query.

@Override
public CompletableFuture<Message> query(Message request) {
    CompletableFuture<Message> future = new CompletableFuture<>();
    try {
        JournalQueryRequest queryRequest = JournalQueryRequest.parseFrom(request.getContent().asReadOnlyByteBuffer());
        LOG.debug("Received query request: {}", queryRequest);
        // give snapshot manager a chance to handle snapshot related requests
        Message reply = mSnapshotManager.handleRequest(queryRequest);
        if (reply != null) {
            future.complete(reply);
            return future;
        }
        // other type of requests.
        if (queryRequest.hasAddQuorumServerRequest()) {
            AddQuorumServerRequest addRequest = queryRequest.getAddQuorumServerRequest();
            return CompletableFuture.supplyAsync(() -> {
                try {
                    mJournalSystem.addQuorumServer(addRequest.getServerAddress());
                } catch (IOException e) {
                    throw new CompletionException(e);
                }
                return Message.EMPTY;
            });
        }
    } catch (Exception e) {
        LOG.error("failed processing request {}", request, e);
        future.completeExceptionally(e);
        return future;
    }
    return super.query(request);
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.apache.ratis.protocol.Message) CompletionException(java.util.concurrent.CompletionException) AddQuorumServerRequest(alluxio.grpc.AddQuorumServerRequest) JournalQueryRequest(alluxio.grpc.JournalQueryRequest) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) FileNotFoundException(java.io.FileNotFoundException) UnavailableException(alluxio.exception.status.UnavailableException) IOException(java.io.IOException)

Example 4 with Message

use of org.apache.ratis.protocol.Message in project alluxio by Alluxio.

the class SnapshotReplicationManagerTest method before.

private void before(int numFollowers) throws Exception {
    mLeader = Mockito.mock(RaftJournalSystem.class);
    Mockito.when(mLeader.isLeader()).thenReturn(true);
    Mockito.when(mLeader.getLocalPeerId()).thenReturn(RaftPeerId.getRaftPeerId("leader"));
    mLeaderStore = getSimpleStateMachineStorage();
    mLeaderSnapshotManager = Mockito.spy(new SnapshotReplicationManager(mLeader, mLeaderStore));
    String serverName = InProcessServerBuilder.generateName();
    mServer = InProcessServerBuilder.forName(serverName).directExecutor().addService(new RaftJournalServiceHandler(mLeaderSnapshotManager)).build();
    mServer.start();
    ManagedChannel channel = InProcessChannelBuilder.forName(serverName).directExecutor().build();
    RaftJournalServiceGrpc.RaftJournalServiceStub stub = RaftJournalServiceGrpc.newStub(channel);
    // mock RaftJournalServiceClient
    mClient = Mockito.mock(RaftJournalServiceClient.class);
    Mockito.doNothing().when(mClient).close();
    // download rpc mock
    Mockito.when(mClient.downloadSnapshot(any())).thenAnswer((args) -> {
        StreamObserver responseObserver = args.getArgument(0, StreamObserver.class);
        return stub.downloadSnapshot(responseObserver);
    });
    // upload rpc mock
    Mockito.when(mClient.uploadSnapshot(any())).thenAnswer((args) -> {
        StreamObserver responseObserver = args.getArgument(0, StreamObserver.class);
        return stub.uploadSnapshot(responseObserver);
    });
    Mockito.doReturn(mClient).when(mLeaderSnapshotManager).getJournalServiceClient();
    for (int i = 0; i < numFollowers; i++) {
        Follower follower = new Follower(mClient);
        mFollowers.put(follower.getRaftPeerId(), follower);
    }
    List<QuorumServerInfo> quorumServerInfos = mFollowers.values().stream().map(follower -> {
        return QuorumServerInfo.newBuilder().setServerAddress(NetAddress.newBuilder().setHost(follower.mHost).setRpcPort(follower.mRpcPort)).build();
    }).collect(Collectors.toList());
    Mockito.when(mLeader.getQuorumServerInfoList()).thenReturn(quorumServerInfos);
    Mockito.when(mLeader.sendMessageAsync(any(), any())).thenAnswer((args) -> {
        RaftPeerId peerId = args.getArgument(0, RaftPeerId.class);
        Message message = args.getArgument(1, Message.class);
        JournalQueryRequest queryRequest = JournalQueryRequest.parseFrom(message.getContent().asReadOnlyByteBuffer());
        Message response = mFollowers.get(peerId).mSnapshotManager.handleRequest(queryRequest);
        RaftClientReply reply = Mockito.mock(RaftClientReply.class);
        Mockito.when(reply.getMessage()).thenReturn(response);
        return CompletableFuture.completedFuture(reply);
    });
}
Also used : StreamObserver(io.grpc.stub.StreamObserver) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BufferUtils(alluxio.util.io.BufferUtils) UploadSnapshotPResponse(alluxio.grpc.UploadSnapshotPResponse) TermIndex(org.apache.ratis.server.protocol.TermIndex) ManagedChannel(io.grpc.ManagedChannel) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) RandomString(net.bytebuddy.utility.RandomString) RaftJournalServiceGrpc(alluxio.grpc.RaftJournalServiceGrpc) PropertyKey(alluxio.conf.PropertyKey) InProcessServerBuilder(io.grpc.inprocess.InProcessServerBuilder) ArrayList(java.util.ArrayList) WaitForOptions(alluxio.util.WaitForOptions) Message(org.apache.ratis.protocol.Message) StreamObserver(io.grpc.stub.StreamObserver) ConfigurationRule(alluxio.ConfigurationRule) JournalQueryRequest(alluxio.grpc.JournalQueryRequest) After(org.junit.After) Map(java.util.Map) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) RaftStorage(org.apache.ratis.server.storage.RaftStorage) Status(io.grpc.Status) Server(io.grpc.Server) InProcessChannelBuilder(io.grpc.inprocess.InProcessChannelBuilder) SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) ServerConfiguration(alluxio.conf.ServerConfiguration) NetAddress(alluxio.grpc.NetAddress) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) FileUtils(org.apache.commons.io.FileUtils) Test(org.junit.Test) IOException(java.io.IOException) SimpleStateMachineStorage(org.apache.ratis.statemachine.impl.SimpleStateMachineStorage) Collectors(java.util.stream.Collectors) StatusRuntimeException(io.grpc.StatusRuntimeException) Mockito(org.mockito.Mockito) RaftStorageImpl(org.apache.ratis.server.storage.RaftStorageImpl) List(java.util.List) Rule(org.junit.Rule) UploadSnapshotPRequest(alluxio.grpc.UploadSnapshotPRequest) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) Assert(org.junit.Assert) CommonUtils(alluxio.util.CommonUtils) TemporaryFolder(org.junit.rules.TemporaryFolder) SnapshotData(alluxio.grpc.SnapshotData) Message(org.apache.ratis.protocol.Message) QuorumServerInfo(alluxio.grpc.QuorumServerInfo) JournalQueryRequest(alluxio.grpc.JournalQueryRequest) RandomString(net.bytebuddy.utility.RandomString) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) ManagedChannel(io.grpc.ManagedChannel) RaftJournalServiceGrpc(alluxio.grpc.RaftJournalServiceGrpc) RaftPeerId(org.apache.ratis.protocol.RaftPeerId)

Aggregations

Message (org.apache.ratis.protocol.Message)4 IOException (java.io.IOException)3 JournalQueryRequest (alluxio.grpc.JournalQueryRequest)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 RaftClientReply (org.apache.ratis.protocol.RaftClientReply)2 RaftStorage (org.apache.ratis.server.storage.RaftStorage)2 ConfigurationRule (alluxio.ConfigurationRule)1 PropertyKey (alluxio.conf.PropertyKey)1 ServerConfiguration (alluxio.conf.ServerConfiguration)1 JournalClosedException (alluxio.exception.JournalClosedException)1 UnavailableException (alluxio.exception.status.UnavailableException)1 AddQuorumServerRequest (alluxio.grpc.AddQuorumServerRequest)1 NetAddress (alluxio.grpc.NetAddress)1 QuorumServerInfo (alluxio.grpc.QuorumServerInfo)1 RaftJournalServiceGrpc (alluxio.grpc.RaftJournalServiceGrpc)1 SnapshotData (alluxio.grpc.SnapshotData)1 UploadSnapshotPRequest (alluxio.grpc.UploadSnapshotPRequest)1 UploadSnapshotPResponse (alluxio.grpc.UploadSnapshotPResponse)1