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);
}
}
}
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());
}
}
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;
}
Aggregations