Search in sources :

Example 1 with ByteBufferCollector

use of io.dingodb.raft.util.ByteBufferCollector in project dingo by dingodb.

the class LocalSnapshotCopier method loadMetaTable.

private void loadMetaTable() throws InterruptedException {
    final ByteBufferCollector metaBuf = ByteBufferCollector.allocate(0);
    Session session = null;
    try {
        this.lock.lock();
        try {
            if (this.cancelled) {
                if (isOk()) {
                    setError(RaftError.ECANCELED, "ECANCELED");
                }
                return;
            }
            session = this.copier.startCopy2IoBuffer(Snapshot.JRAFT_SNAPSHOT_META_FILE, metaBuf, null);
            this.curSession = session;
        } finally {
            this.lock.unlock();
        }
        // join out of lock.
        session.join();
        this.lock.lock();
        try {
            this.curSession = null;
        } finally {
            this.lock.unlock();
        }
        if (!session.status().isOk() && isOk()) {
            LOG.warn("Fail to copy meta file: {}", session.status());
            setError(session.status().getCode(), session.status().getErrorMsg());
            return;
        }
        if (!this.remoteSnapshot.getMetaTable().loadFromIoBufferAsRemote(metaBuf.getBuffer())) {
            LOG.warn("Bad meta_table format");
            setError(-1, "Bad meta_table format from remote");
            return;
        }
        Requires.requireTrue(this.remoteSnapshot.getMetaTable().hasMeta(), "Invalid remote snapshot meta:%s", this.remoteSnapshot.getMetaTable().getMeta());
    } finally {
        if (session != null) {
            Utils.closeQuietly(session);
        }
    }
}
Also used : ByteBufferCollector(io.dingodb.raft.util.ByteBufferCollector) Session(io.dingodb.raft.storage.snapshot.remote.Session)

Example 2 with ByteBufferCollector

use of io.dingodb.raft.util.ByteBufferCollector in project dingo by dingodb.

the class FileService method handleGetFile.

/**
 * Handle GetFileRequest, run the response or set the response with done.
 */
public Message handleGetFile(final RpcRequests.GetFileRequest request, final RpcRequestClosure done) {
    if (request.getCount() <= 0 || request.getOffset() < 0) {
        return // 
        RpcFactoryHelper.responseFactory().newResponse(RpcRequests.GetFileResponse.getDefaultInstance(), RaftError.EREQUEST, "Invalid request: %s", request);
    }
    final FileReader reader = this.fileReaderMap.get(request.getReaderId());
    if (reader == null) {
        return // 
        RpcFactoryHelper.responseFactory().newResponse(RpcRequests.GetFileResponse.getDefaultInstance(), RaftError.ENOENT, "Fail to find reader=%d", request.getReaderId());
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("GetFile from {} path={} filename={} offset={} count={}", done.getRpcCtx().getRemoteAddress(), reader.getPath(), request.getFilename(), request.getOffset(), request.getCount());
    }
    final ByteBufferCollector dataBuffer = ByteBufferCollector.allocate();
    final RpcRequests.GetFileResponse.Builder responseBuilder = RpcRequests.GetFileResponse.newBuilder();
    try {
        final int read = reader.readFile(dataBuffer, request.getFilename(), request.getOffset(), request.getCount());
        responseBuilder.setReadSize(read);
        responseBuilder.setEof(read == FileReader.EOF);
        final ByteBuffer buf = dataBuffer.getBuffer();
        buf.flip();
        if (!buf.hasRemaining()) {
            // skip empty data
            responseBuilder.setData(ByteString.EMPTY);
        } else {
            // TODO check hole
            responseBuilder.setData(ZeroByteStringHelper.wrap(buf));
        }
        return responseBuilder.build();
    } catch (final RetryAgainException e) {
        return // 
        RpcFactoryHelper.responseFactory().newResponse(RpcRequests.GetFileResponse.getDefaultInstance(), RaftError.EAGAIN, "Fail to read from path=%s filename=%s with error: %s", reader.getPath(), request.getFilename(), e.getMessage());
    } catch (final IOException e) {
        LOG.error("Fail to read file path={} filename={}", reader.getPath(), request.getFilename(), e);
        return // 
        RpcFactoryHelper.responseFactory().newResponse(RpcRequests.GetFileResponse.getDefaultInstance(), RaftError.EIO, "Fail to read from path=%s filename=%s", reader.getPath(), request.getFilename());
    }
}
Also used : ByteBufferCollector(io.dingodb.raft.util.ByteBufferCollector) FileReader(io.dingodb.raft.storage.io.FileReader) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) RetryAgainException(io.dingodb.raft.error.RetryAgainException)

Example 3 with ByteBufferCollector

use of io.dingodb.raft.util.ByteBufferCollector in project dingo by dingodb.

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 RpcRequests.AppendEntriesRequest.Builder rb = RpcRequests.AppendEntriesRequest.newBuilder();
    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 {
        for (int i = 0; i < maxEntriesSize; i++) {
            final RaftOutter.EntryMeta.Builder emb = RaftOutter.EntryMeta.newBuilder();
            if (!prepareEntry(nextSendingIndex, i, emb, byteBufList)) {
                break;
            }
            rb.addEntries(emb.build());
        }
        if (rb.getEntriesCount() == 0) {
            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.setData(ZeroByteStringHelper.wrap(buf));
        }
    } finally {
        RecycleUtil.recycle(byteBufList);
    }
    final RpcRequests.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.getCommittedIndex(), request.getPrevLogIndex(), request.getPrevLogTerm(), nextSendingIndex, request.getEntriesCount());
    }
    this.statInfo.runningState = RunningState.APPENDING_ENTRIES;
    this.statInfo.firstLogIndex = rb.getPrevLogIndex() + 1;
    this.statInfo.lastLogIndex = rb.getPrevLogIndex() + rb.getEntriesCount();
    final Recyclable recyclable = dataBuf;
    final int v = this.version;
    final long monotonicSendTimeMs = Utils.monotonicMs();
    final int seq = getAndIncrementReqSeq();
    this.appendEntriesCounter++;
    Future<Message> rpcFuture = null;
    try {
        rpcFuture = this.rpcService.appendEntries(this.options.getPeerId().getEndpoint(), request, -1, new RpcResponseClosureAdapter<RpcRequests.AppendEntriesResponse>() {

            @Override
            public void run(final Status status) {
                // TODO: recycle on send success, not response received.
                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, request.getEntriesCount(), request.getData().size(), seq, rpcFuture);
    return true;
}
Also used : Status(io.dingodb.raft.Status) RecyclableByteBufferList(io.dingodb.raft.util.RecyclableByteBufferList) Message(com.google.protobuf.Message) RpcResponseClosureAdapter(io.dingodb.raft.rpc.RpcResponseClosureAdapter) RpcRequests(io.dingodb.raft.rpc.RpcRequests) ByteBuffer(java.nio.ByteBuffer) ByteBufferCollector(io.dingodb.raft.util.ByteBufferCollector) Recyclable(io.dingodb.raft.util.Recyclable)

Aggregations

ByteBufferCollector (io.dingodb.raft.util.ByteBufferCollector)3 ByteBuffer (java.nio.ByteBuffer)2 Message (com.google.protobuf.Message)1 Status (io.dingodb.raft.Status)1 RetryAgainException (io.dingodb.raft.error.RetryAgainException)1 RpcRequests (io.dingodb.raft.rpc.RpcRequests)1 RpcResponseClosureAdapter (io.dingodb.raft.rpc.RpcResponseClosureAdapter)1 FileReader (io.dingodb.raft.storage.io.FileReader)1 Session (io.dingodb.raft.storage.snapshot.remote.Session)1 Recyclable (io.dingodb.raft.util.Recyclable)1 RecyclableByteBufferList (io.dingodb.raft.util.RecyclableByteBufferList)1 IOException (java.io.IOException)1