Search in sources :

Example 6 with ByteString

use of org.apache.ignite.raft.jraft.util.ByteString in project ignite-3 by apache.

the class Replicator method sendEntries.

/**
 * Send log entries to follower, returns true when success, otherwise false and unlock the id.
 *
 * @param nextSendingIndex next sending index
 * @return send result.
 */
private boolean sendEntries(final long nextSendingIndex) {
    final AppendEntriesRequestBuilder rb = raftOptions.getRaftMessagesFactory().appendEntriesRequest();
    if (!fillCommonFields(rb, nextSendingIndex - 1, false)) {
        // unlock id in installSnapshot
        installSnapshot();
        return false;
    }
    ByteBufferCollector dataBuf = null;
    final int maxEntriesSize = this.raftOptions.getMaxEntriesSize();
    final RecyclableByteBufferList byteBufList = RecyclableByteBufferList.newInstance();
    try {
        List<RaftOutter.EntryMeta> entries = new ArrayList<>();
        for (int i = 0; i < maxEntriesSize; i++) {
            final EntryMetaBuilder emb = raftOptions.getRaftMessagesFactory().entryMeta();
            if (!prepareEntry(nextSendingIndex, i, emb, byteBufList)) {
                break;
            }
            entries.add(emb.build());
        }
        rb.entriesList(entries);
        if (entries.isEmpty()) {
            if (nextSendingIndex < this.options.getLogManager().getFirstLogIndex()) {
                installSnapshot();
                return false;
            }
            // _id is unlock in _wait_more
            waitMoreEntries(nextSendingIndex);
            return false;
        }
        if (byteBufList.getCapacity() > 0) {
            dataBuf = ByteBufferCollector.allocateByRecyclers(byteBufList.getCapacity());
            for (final ByteBuffer b : byteBufList) {
                dataBuf.put(b);
            }
            final ByteBuffer buf = dataBuf.getBuffer();
            buf.flip();
            rb.data(new ByteString(buf));
        }
    } finally {
        RecycleUtil.recycle(byteBufList);
    }
    final AppendEntriesRequest request = rb.build();
    if (LOG.isDebugEnabled()) {
        LOG.debug("Node {} send AppendEntriesRequest to {} term {} lastCommittedIndex {} prevLogIndex {} prevLogTerm {} logIndex {} count {}", this.options.getNode().getNodeId(), this.options.getPeerId(), this.options.getTerm(), request.committedIndex(), request.prevLogIndex(), request.prevLogTerm(), nextSendingIndex, Utils.size(request.entriesList()));
    }
    this.statInfo.runningState = RunningState.APPENDING_ENTRIES;
    this.statInfo.firstLogIndex = request.prevLogIndex() + 1;
    this.statInfo.lastLogIndex = request.prevLogIndex() + Utils.size(request.entriesList());
    final Recyclable recyclable = dataBuf;
    final int v = this.version;
    final long monotonicSendTimeMs = Utils.monotonicMs();
    final int seq = getAndIncrementReqSeq();
    Future<Message> rpcFuture = null;
    try {
        rpcFuture = this.rpcService.appendEntries(this.options.getPeerId().getEndpoint(), request, -1, new RpcResponseClosureAdapter<AppendEntriesResponse>() {

            @Override
            public void run(final Status status) {
                if (status.isOk()) {
                    // TODO: recycle on send success, not response received IGNITE-14832.
                    // Also, this closure can be executed when rpcFuture was cancelled, but the request was not sent (meaning
                    // it's too early to recycle byte buffer)
                    RecycleUtil.recycle(recyclable);
                }
                onRpcReturned(Replicator.this.id, RequestType.AppendEntries, status, request, getResponse(), seq, v, monotonicSendTimeMs);
            }
        });
    } catch (final Throwable t) {
        RecycleUtil.recycle(recyclable);
        ThrowUtil.throwException(t);
    }
    addInflight(RequestType.AppendEntries, nextSendingIndex, Utils.size(request.entriesList()), request.data() == null ? 0 : request.data().size(), seq, rpcFuture);
    return true;
}
Also used : Status(org.apache.ignite.raft.jraft.Status) RecyclableByteBufferList(org.apache.ignite.raft.jraft.util.RecyclableByteBufferList) Message(org.apache.ignite.raft.jraft.rpc.Message) ByteString(org.apache.ignite.raft.jraft.util.ByteString) ArrayList(java.util.ArrayList) RpcResponseClosureAdapter(org.apache.ignite.raft.jraft.rpc.RpcResponseClosureAdapter) AppendEntriesRequest(org.apache.ignite.raft.jraft.rpc.RpcRequests.AppendEntriesRequest) ByteBuffer(java.nio.ByteBuffer) ByteBufferCollector(org.apache.ignite.raft.jraft.util.ByteBufferCollector) AppendEntriesRequestBuilder(org.apache.ignite.raft.jraft.rpc.AppendEntriesRequestBuilder) Recyclable(org.apache.ignite.raft.jraft.util.Recyclable) EntryMetaBuilder(org.apache.ignite.raft.jraft.entity.EntryMetaBuilder)

Example 7 with ByteString

use of org.apache.ignite.raft.jraft.util.ByteString in project ignite-3 by apache.

the class FileService method handleGetFile.

/**
 * Handle GetFileRequest, run the response or set the response with done.
 */
public Message handleGetFile(final GetFileRequest request, final RpcRequestClosure done) {
    if (request.count() <= 0 || request.offset() < 0) {
        return // 
        RaftRpcFactory.DEFAULT.newResponse(msgFactory, RaftError.EREQUEST, "Invalid request: %s", request);
    }
    final FileReader reader = this.fileReaderMap.get(request.readerId());
    if (LOG.isDebugEnabled()) {
        LOG.info("handleGetFile id={}, name={}, offset={}, cnt={}", request.readerId(), request.filename(), request.offset(), request.count());
    }
    if (reader == null) {
        return // 
        RaftRpcFactory.DEFAULT.newResponse(msgFactory, RaftError.ENOENT, "Fail to find reader=%d", request.readerId());
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("GetFile from {} path={} filename={} offset={} count={}", done.getRpcCtx().getRemoteAddress(), reader.getPath(), request.filename(), request.offset(), request.count());
    }
    final ByteBufferCollector dataBuffer = ByteBufferCollector.allocate();
    final GetFileResponseBuilder responseBuilder = msgFactory.getFileResponse();
    try {
        final int read = reader.readFile(dataBuffer, request.filename(), request.offset(), request.count());
        responseBuilder.readSize(read);
        responseBuilder.eof(read == FileReader.EOF);
        final ByteBuffer buf = dataBuffer.getBuffer();
        buf.flip();
        if (!buf.hasRemaining()) {
            // skip empty data
            responseBuilder.data(ByteString.EMPTY);
        } else {
            // TODO check hole https://issues.apache.org/jira/browse/IGNITE-14832
            responseBuilder.data(new ByteString(buf));
        }
        return responseBuilder.build();
    } catch (final RetryAgainException e) {
        return // 
        RaftRpcFactory.DEFAULT.newResponse(msgFactory, RaftError.EAGAIN, "Fail to read from path=%s filename=%s with error: %s", reader.getPath(), request.filename(), e.getMessage());
    } catch (final IOException e) {
        LOG.error("Fail to read file path={} filename={}", e, reader.getPath(), request.filename());
        return // 
        RaftRpcFactory.DEFAULT.newResponse(msgFactory, RaftError.EIO, "Fail to read from path=%s filename=%s", reader.getPath(), request.filename());
    }
}
Also used : ByteBufferCollector(org.apache.ignite.raft.jraft.util.ByteBufferCollector) GetFileResponseBuilder(org.apache.ignite.raft.jraft.rpc.GetFileResponseBuilder) ByteString(org.apache.ignite.raft.jraft.util.ByteString) FileReader(org.apache.ignite.raft.jraft.storage.io.FileReader) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) RetryAgainException(org.apache.ignite.raft.jraft.error.RetryAgainException)

Example 8 with ByteString

use of org.apache.ignite.raft.jraft.util.ByteString in project ignite-3 by apache.

the class ReadOnlyServiceImpl method executeReadIndexEvents.

private void executeReadIndexEvents(final List<ReadIndexEvent> events) {
    if (events.isEmpty())
        return;
    ReadIndexRequestBuilder rb = raftOptions.getRaftMessagesFactory().readIndexRequest().groupId(this.node.getGroupId()).serverId(this.node.getServerId().toString());
    List<ReadIndexState> states = new ArrayList<>(events.size());
    List<ByteString> entries = new ArrayList<>(events.size());
    for (ReadIndexEvent event : events) {
        byte[] ctx = event.requestContext.get();
        entries.add(ctx == null ? ByteString.EMPTY : new ByteString(ctx));
        states.add(new ReadIndexState(event.requestContext, event.done, event.startTime));
    }
    ReadIndexRequest request = rb.entriesList(entries).build();
    this.node.handleReadIndexRequest(request, new ReadIndexResponseClosure(states, request));
}
Also used : ReadIndexRequest(org.apache.ignite.raft.jraft.rpc.RpcRequests.ReadIndexRequest) ByteString(org.apache.ignite.raft.jraft.util.ByteString) ReadIndexState(org.apache.ignite.raft.jraft.entity.ReadIndexState) ReadIndexRequestBuilder(org.apache.ignite.raft.jraft.rpc.ReadIndexRequestBuilder) ArrayList(java.util.ArrayList)

Example 9 with ByteString

use of org.apache.ignite.raft.jraft.util.ByteString in project ignite-3 by apache.

the class SnapshotExecutorTest method testInstallSnapshot.

@Test
public void testInstallSnapshot() throws Exception {
    RaftMessagesFactory msgFactory = raftOptions.getRaftMessagesFactory();
    final RpcRequests.InstallSnapshotRequest irb = msgFactory.installSnapshotRequest().groupId("test").peerId(addr.toString()).serverId("localhost:8080").uri("remote://localhost:8080/99").term(0).meta(msgFactory.snapshotMeta().lastIncludedIndex(1).lastIncludedTerm(2).build()).build();
    Mockito.when(raftClientService.connect(new Endpoint("localhost", 8080))).thenReturn(true);
    final CompletableFuture<Message> fut = new CompletableFuture<>();
    final GetFileRequestBuilder rb = msgFactory.getFileRequest().readerId(99).filename(Snapshot.JRAFT_SNAPSHOT_META_FILE).count(Integer.MAX_VALUE).offset(0).readPartly(true);
    // Mock get metadata
    ArgumentCaptor<RpcResponseClosure> argument = ArgumentCaptor.forClass(RpcResponseClosure.class);
    Mockito.when(raftClientService.getFile(eq(new Endpoint("localhost", 8080)), eq(rb.build()), eq(copyOpts.getTimeoutMs()), argument.capture())).thenReturn(fut);
    Future<?> snapFut = Utils.runInThread(ForkJoinPool.commonPool(), () -> executor.installSnapshot(irb, msgFactory.installSnapshotResponse(), new RpcRequestClosure(asyncCtx, msgFactory)));
    assertTrue(TestUtils.waitForArgumentCapture(argument, 5_000));
    RpcResponseClosure<RpcRequests.GetFileResponse> closure = argument.getValue();
    final ByteBuffer metaBuf = table.saveToByteBufferAsRemote();
    closure.setResponse(msgFactory.getFileResponse().readSize(metaBuf.remaining()).eof(true).data(new ByteString(metaBuf)).build());
    // Mock get file
    argument = ArgumentCaptor.forClass(RpcResponseClosure.class);
    rb.filename("testFile");
    rb.count(raftOptions.getMaxByteCountPerRpc());
    Mockito.when(raftClientService.getFile(eq(new Endpoint("localhost", 8080)), eq(rb.build()), eq(copyOpts.getTimeoutMs()), argument.capture())).thenReturn(fut);
    closure.run(Status.OK());
    assertTrue(TestUtils.waitForArgumentCapture(argument, 5_000));
    closure = argument.getValue();
    closure.setResponse(msgFactory.getFileResponse().readSize(100).eof(true).data(new ByteString(new byte[100])).build());
    ArgumentCaptor<LoadSnapshotClosure> loadSnapshotArg = ArgumentCaptor.forClass(LoadSnapshotClosure.class);
    Mockito.when(fSMCaller.onSnapshotLoad(loadSnapshotArg.capture())).thenReturn(true);
    closure.run(Status.OK());
    assertTrue(TestUtils.waitForArgumentCapture(loadSnapshotArg, 5_000));
    final LoadSnapshotClosure done = loadSnapshotArg.getValue();
    final SnapshotReader reader = done.start();
    assertNotNull(reader);
    assertEquals(1, reader.listFiles().size());
    assertTrue(reader.listFiles().contains("testFile"));
    done.run(Status.OK());
    executor.join();
    assertTrue(snapFut.isDone());
    assertEquals(2, executor.getLastSnapshotTerm());
    assertEquals(1, executor.getLastSnapshotIndex());
}
Also used : Message(org.apache.ignite.raft.jraft.rpc.Message) ByteString(org.apache.ignite.raft.jraft.util.ByteString) RpcResponseClosure(org.apache.ignite.raft.jraft.rpc.RpcResponseClosure) RaftMessagesFactory(org.apache.ignite.raft.jraft.RaftMessagesFactory) RpcRequests(org.apache.ignite.raft.jraft.rpc.RpcRequests) ByteBuffer(java.nio.ByteBuffer) RpcRequestClosure(org.apache.ignite.raft.jraft.rpc.RpcRequestClosure) LoadSnapshotClosure(org.apache.ignite.raft.jraft.closure.LoadSnapshotClosure) CompletableFuture(java.util.concurrent.CompletableFuture) GetFileRequestBuilder(org.apache.ignite.raft.jraft.rpc.GetFileRequestBuilder) Endpoint(org.apache.ignite.raft.jraft.util.Endpoint) SnapshotReader(org.apache.ignite.raft.jraft.storage.snapshot.SnapshotReader) LocalSnapshotReader(org.apache.ignite.raft.jraft.storage.snapshot.local.LocalSnapshotReader) Test(org.junit.jupiter.api.Test)

Example 10 with ByteString

use of org.apache.ignite.raft.jraft.util.ByteString in project ignite-3 by apache.

the class CopySessionTest method testOnRpcReturnedEOF.

@Test
public void testOnRpcReturnedEOF() throws Exception {
    final CountDownLatch latch = new CountDownLatch(1);
    Thread t = new Thread(() -> {
        try {
            // test join, should return
            session.join();
            latch.countDown();
        } catch (final InterruptedException e) {
        // No-op.
        }
    });
    try {
        t.start();
        assertNull(this.session.getRpcCall());
        final ByteBufferCollector bufRef = ByteBufferCollector.allocate(0);
        this.session.setDestBuf(bufRef);
        this.session.onRpcReturned(Status.OK(), raftOpts.getRaftMessagesFactory().getFileResponse().readSize(100).eof(true).data(new ByteString(new byte[100])).build());
        assertEquals(100, bufRef.capacity());
        // should be flip
        assertEquals(0, bufRef.getBuffer().position());
        assertEquals(100, bufRef.getBuffer().remaining());
        assertNull(this.session.getRpcCall());
        latch.await();
    } finally {
        t.join();
    }
}
Also used : ByteBufferCollector(org.apache.ignite.raft.jraft.util.ByteBufferCollector) ByteString(org.apache.ignite.raft.jraft.util.ByteString) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test)

Aggregations

ByteString (org.apache.ignite.raft.jraft.util.ByteString)11 ByteBuffer (java.nio.ByteBuffer)7 ByteBufferCollector (org.apache.ignite.raft.jraft.util.ByteBufferCollector)7 Message (org.apache.ignite.raft.jraft.rpc.Message)5 Test (org.junit.jupiter.api.Test)5 CompletableFuture (java.util.concurrent.CompletableFuture)4 RpcRequests (org.apache.ignite.raft.jraft.rpc.RpcRequests)4 ArrayList (java.util.ArrayList)3 AppendEntriesRequestBuilder (org.apache.ignite.raft.jraft.rpc.AppendEntriesRequestBuilder)2 GetFileRequestBuilder (org.apache.ignite.raft.jraft.rpc.GetFileRequestBuilder)2 RpcResponseClosure (org.apache.ignite.raft.jraft.rpc.RpcResponseClosure)2 SnapshotReader (org.apache.ignite.raft.jraft.storage.snapshot.SnapshotReader)2 Endpoint (org.apache.ignite.raft.jraft.util.Endpoint)2 IOException (java.io.IOException)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 Future (java.util.concurrent.Future)1 ScheduledFuture (java.util.concurrent.ScheduledFuture)1 RaftMessagesFactory (org.apache.ignite.raft.jraft.RaftMessagesFactory)1 Status (org.apache.ignite.raft.jraft.Status)1 LoadSnapshotClosure (org.apache.ignite.raft.jraft.closure.LoadSnapshotClosure)1