Search in sources :

Example 1 with Recyclable

use of org.apache.ignite.raft.jraft.util.Recyclable 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)

Aggregations

ByteBuffer (java.nio.ByteBuffer)1 ArrayList (java.util.ArrayList)1 Status (org.apache.ignite.raft.jraft.Status)1 EntryMetaBuilder (org.apache.ignite.raft.jraft.entity.EntryMetaBuilder)1 AppendEntriesRequestBuilder (org.apache.ignite.raft.jraft.rpc.AppendEntriesRequestBuilder)1 Message (org.apache.ignite.raft.jraft.rpc.Message)1 AppendEntriesRequest (org.apache.ignite.raft.jraft.rpc.RpcRequests.AppendEntriesRequest)1 RpcResponseClosureAdapter (org.apache.ignite.raft.jraft.rpc.RpcResponseClosureAdapter)1 ByteBufferCollector (org.apache.ignite.raft.jraft.util.ByteBufferCollector)1 ByteString (org.apache.ignite.raft.jraft.util.ByteString)1 Recyclable (org.apache.ignite.raft.jraft.util.Recyclable)1 RecyclableByteBufferList (org.apache.ignite.raft.jraft.util.RecyclableByteBufferList)1