Java源码示例:com.alipay.sofa.jraft.Closure
示例1
@Override
public void save(final SnapshotWriter writer, final Region region, final Closure done,
final ExecutorService executor) {
final String writerPath = writer.getPath();
final String snapshotPath = Paths.get(writerPath, SNAPSHOT_DIR).toString();
try {
doSnapshotSave(snapshotPath, region, executor).whenComplete((metaBuilder, throwable) -> {
if (throwable == null) {
executor.execute(() -> compressSnapshot(writer, metaBuilder, done));
} else {
LOG.error("Fail to save snapshot, path={}, file list={}, {}.", writerPath, writer.listFiles(),
StackTraceUtil.stackTrace(throwable));
done.run(new Status(RaftError.EIO, "Fail to save snapshot at %s, error is %s", writerPath,
throwable.getMessage()));
}
});
} catch (final Throwable t) {
LOG.error("Fail to save snapshot, path={}, file list={}, {}.", writerPath, writer.listFiles(),
StackTraceUtil.stackTrace(t));
done.run(new Status(RaftError.EIO, "Fail to save snapshot at %s, error is %s", writerPath,
t.getMessage()));
}
}
示例2
protected void compressSnapshot(final SnapshotWriter writer, final LocalFileMeta.Builder metaBuilder,
final Closure done) {
final String writerPath = writer.getPath();
final String outputFile = Paths.get(writerPath, SNAPSHOT_ARCHIVE).toString();
try {
final Checksum checksum = new CRC64();
ZipUtil.compress(writerPath, SNAPSHOT_DIR, outputFile, checksum);
metaBuilder.setChecksum(Long.toHexString(checksum.getValue()));
if (writer.addFile(SNAPSHOT_ARCHIVE, metaBuilder.build())) {
done.run(Status.OK());
} else {
done.run(new Status(RaftError.EIO, "Fail to add snapshot file: %s", writerPath));
}
} catch (final Throwable t) {
LOG.error("Fail to compress snapshot, path={}, file list={}, {}.", writerPath, writer.listFiles(),
StackTraceUtil.stackTrace(t));
done.run(new Status(RaftError.EIO, "Fail to compress snapshot at %s, error is %s", writerPath, t
.getMessage()));
}
}
示例3
@Override
public void onSnapshotSave(final SnapshotWriter writer, final Closure done) {
final Map<String, Long> values = new HashMap<>();
for (final Map.Entry<String, AtomicLong> entry : this.counters.entrySet()) {
values.put(entry.getKey(), entry.getValue().get());
}
Utils.runInThread(() -> {
final AtomicSnapshotFile snapshot = new AtomicSnapshotFile(writer.getPath() + File.separator + "data");
if (snapshot.save(values)) {
if (writer.addFile("data")) {
done.run(Status.OK());
} else {
done.run(new Status(RaftError.EIO, "Fail to add file to writer"));
}
} else {
done.run(new Status(RaftError.EIO, "Fail to save counter snapshot %s", snapshot.getPath()));
}
});
}
示例4
@Override
public void clear() {
List<Closure> savedQueue;
this.lock.lock();
try {
this.firstIndex = 0;
savedQueue = this.queue;
this.queue = new LinkedList<>();
} finally {
this.lock.unlock();
}
final Status status = new Status(RaftError.EPERM, "Leader stepped down");
Utils.runInThread(() -> {
for (final Closure done : savedQueue) {
if (done != null) {
done.run(status);
}
}
});
}
示例5
/**
* Called by leader, otherwise the behavior is undefined
* Store application context before replication.
*
* @param conf current configuration
* @param oldConf old configuration
* @param done callback
* @return returns true on success
*/
public boolean appendPendingTask(final Configuration conf, final Configuration oldConf, final Closure done) {
final Ballot bl = new Ballot();
if (!bl.init(conf, oldConf)) {
LOG.error("Fail to init ballot.");
return false;
}
final long stamp = this.stampedLock.writeLock();
try {
if (this.pendingIndex <= 0) {
LOG.error("Fail to appendingTask, pendingIndex={}.", this.pendingIndex);
return false;
}
this.pendingMetaQueue.add(bl);
this.closureQueue.appendPendingClosure(done);
return true;
} finally {
this.stampedLock.unlockWrite(stamp);
}
}
示例6
private void afterShutdown() {
List<Closure> savedDoneList = null;
this.writeLock.lock();
try {
if (!this.shutdownContinuations.isEmpty()) {
savedDoneList = new ArrayList<>(this.shutdownContinuations);
}
if (this.logStorage != null) {
this.logStorage.shutdown();
}
this.state = State.STATE_SHUTDOWN;
} finally {
this.writeLock.unlock();
}
if (savedDoneList != null) {
for (final Closure closure : savedDoneList) {
Utils.runClosureInThread(closure);
}
}
}
示例7
@Test
public void testHandleRequest() {
this.mockNodes(3);
Mockito.when(this.node.getGroupId()).thenReturn(this.groupId);
PeerId peerId = new PeerId();
peerId.parse(this.peerIdStr);
Mockito.when(this.node.getOptions()).thenReturn(new NodeOptions());
Mockito.when(this.node.getNodeId()).thenReturn(new NodeId("test", peerId));
NodeManager.getInstance().addAddress(peerId.getEndpoint());
NodeManager.getInstance().add(this.node);
BaseCliRequestProcessor<T> processor = newProcessor();
processor.handleRequest(this.asyncContext, createRequest(this.groupId, peerId));
ArgumentCaptor<Closure> doneArg = ArgumentCaptor.forClass(Closure.class);
verify(processor.interest(), this.node, doneArg);
}
示例8
@Test
public void testResetFirstIndex() {
assertEquals(0, this.queue.getFirstIndex());
this.queue.resetFirstIndex(10);
assertEquals(10, this.queue.getFirstIndex());
for (int i = 0; i < 10; i++) {
this.queue.appendPendingClosure(mockClosure(null));
}
List<Closure> closures = new ArrayList<>();
assertEquals(5, this.queue.popClosureUntil(4, closures));
assertTrue(closures.isEmpty());
assertEquals(4, this.queue.popClosureUntil(3, closures));
assertTrue(closures.isEmpty());
assertEquals(10, this.queue.popClosureUntil(19, closures));
assertEquals(20, this.queue.getFirstIndex());
assertEquals(10, closures.size());
// empty ,return index+1
assertEquals(21, this.queue.popClosureUntil(20, closures));
assertTrue(closures.isEmpty());
}
示例9
@Override
public void onSnapshotSave(final SnapshotWriter writer, final Closure done) {
final long currVal = this.value.get();
Utils.runInThread(() -> {
final CounterSnapshotFile snapshot = new CounterSnapshotFile(writer.getPath() + File.separator + "data");
if (snapshot.save(currVal)) {
if (writer.addFile("data")) {
done.run(Status.OK());
} else {
done.run(new Status(RaftError.EIO, "Fail to add file to writer"));
}
} else {
done.run(new Status(RaftError.EIO, "Fail to save counter snapshot %s", snapshot.getPath()));
}
});
}
示例10
@Override
public void onSnapshotSave(final SnapshotWriter writer, final Closure done) {
this.saveSnapshotTimes++;
final String path = writer.getPath() + File.separator + "data";
final File file = new File(path);
try (FileOutputStream fout = new FileOutputStream(file);
BufferedOutputStream out = new BufferedOutputStream(fout)) {
this.lock.lock();
try {
for (final ByteBuffer buf : this.logs) {
final byte[] bs = new byte[4];
Bits.putInt(bs, 0, buf.remaining());
out.write(bs);
out.write(buf.array());
}
this.snapshotIndex = this.appliedIndex;
} finally {
this.lock.unlock();
}
System.out.println("Node<" + this.address + "> saved snapshot into " + file);
writer.addFile("data");
done.run(Status.OK());
} catch (final IOException e) {
e.printStackTrace();
done.run(new Status(RaftError.EIO, "Fail to save snapshot"));
}
}
示例11
/**
* Creates a task with data/done/expectedTerm.
*/
public Task(ByteBuffer data, Closure done, long expectedTerm) {
super();
this.data = data;
this.done = done;
this.expectedTerm = expectedTerm;
}
示例12
/**
* Waiting for all tasks to complete with a timeout millis.
*
* @param tasks task list
* @param timeoutMillis the maximum millis to wait
* @return the closure list in the tasks
* @throws InterruptedException if the current thread is interrupted while waiting
* @throws TimeoutException if timeout
* @since 1.3.1
*/
public static List<Closure> joinAll(final List<Task> tasks, long timeoutMillis) throws InterruptedException,
TimeoutException {
final List<Closure> closures = new ArrayList<>(tasks.size());
for (final Task t : tasks) {
final long start = System.nanoTime();
closures.add(t.join(timeoutMillis));
timeoutMillis -= TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
if (timeoutMillis <= 0) {
throw new TimeoutException("joined timeout");
}
}
return closures;
}
示例13
/**
* Run closure with OK status in thread pool.
*/
public static Future<?> runClosureInThread(final Closure done) {
if (done == null) {
return null;
}
return runClosureInThread(done, Status.OK());
}
示例14
/**
* Run closure with status in thread pool.
*/
public static Future<?> runClosureInThread(final Closure done, final Status status) {
if (done == null) {
return null;
}
return runInThread(() -> {
try {
done.run(status);
} catch (final Throwable t) {
LOG.error("Fail to run done closure", t);
}
});
}
示例15
/**
* Run closure with OK status in thread pool.
*/
public static Future<?> runClosureInThread(final Closure done) {
if (done == null) {
return null;
}
return runClosureInThread(done, Status.OK());
}
示例16
/**
* Run closure with status in thread pool.
*/
public static Future<?> runClosureInThread(final Closure done, final Status status) {
if (done == null) {
return null;
}
return runInThread(() -> {
try {
done.run(status);
} catch (final Throwable t) {
LOG.error("Fail to run done closure", t);
}
});
}
示例17
@Override
public void appendPendingClosure(final Closure closure) {
this.lock.lock();
try {
this.queue.add(closure);
} finally {
this.lock.unlock();
}
}
示例18
@Override
public long popClosureUntil(final long endIndex, final List<Closure> closures, final List<TaskClosure> taskClosures) {
closures.clear();
if (taskClosures != null) {
taskClosures.clear();
}
this.lock.lock();
try {
final int queueSize = this.queue.size();
if (queueSize == 0 || endIndex < this.firstIndex) {
return endIndex + 1;
}
if (endIndex > this.firstIndex + queueSize - 1) {
LOG.error("Invalid endIndex={}, firstIndex={}, closureQueueSize={}", endIndex, this.firstIndex,
queueSize);
return -1;
}
final long outFirstIndex = this.firstIndex;
for (long i = outFirstIndex; i <= endIndex; i++) {
final Closure closure = this.queue.pollFirst();
if (taskClosures != null && closure instanceof TaskClosure) {
taskClosures.add((TaskClosure) closure);
}
closures.add(closure);
}
this.firstIndex = endIndex + 1;
return outFirstIndex;
} finally {
this.lock.unlock();
}
}
示例19
private boolean passByStatus(final Closure done) {
final Status status = this.error.getStatus();
if (!status.isOk()) {
if (done != null) {
done.run(new Status(RaftError.EINVAL, "FSMCaller is in bad status=`%s`", status));
return false;
}
}
return true;
}
示例20
public IteratorImpl(final StateMachine fsm, final LogManager logManager, final List<Closure> closures,
final long firstClosureIndex, final long lastAppliedIndex, final long committedIndex,
final AtomicLong applyingIndex) {
super();
this.fsm = fsm;
this.logManager = logManager;
this.closures = closures;
this.firstClosureIndex = firstClosureIndex;
this.currentIndex = lastAppliedIndex;
this.committedIndex = committedIndex;
this.applyingIndex = applyingIndex;
next();
}
示例21
protected void runTheRestClosureWithError() {
for (long i = Math.max(this.currentIndex, this.firstClosureIndex); i <= this.committedIndex; i++) {
final Closure done = this.closures.get((int) (i - this.firstClosureIndex));
if (done != null) {
Requires.requireNonNull(this.error, "error");
Requires.requireNonNull(this.error.getStatus(), "error.status");
final Status status = this.error.getStatus();
Utils.runClosureInThread(done, status);
}
}
}
示例22
/**
* Start change configuration.
*/
void start(final Configuration oldConf, final Configuration newConf, final Closure done) {
if (isBusy()) {
if (done != null) {
Utils.runClosureInThread(done, new Status(RaftError.EBUSY, "Already in busy stage."));
}
throw new IllegalStateException("Busy stage");
}
if (this.done != null) {
if (done != null) {
Utils.runClosureInThread(done, new Status(RaftError.EINVAL, "Already have done closure."));
}
throw new IllegalArgumentException("Already have done closure");
}
this.done = done;
this.stage = Stage.STAGE_CATCHING_UP;
this.oldPeers = oldConf.listPeers();
this.newPeers = newConf.listPeers();
this.oldLearners = oldConf.listLearners();
this.newLearners = newConf.listLearners();
final Configuration adding = new Configuration();
final Configuration removing = new Configuration();
newConf.diff(oldConf, adding, removing);
this.nchanges = adding.size() + removing.size();
addNewLearners();
if (adding.isEmpty()) {
nextStage();
return;
}
addNewPeers(adding);
}
示例23
private void unsafeRegisterConfChange(final Configuration oldConf, final Configuration newConf, final Closure done) {
Requires.requireTrue(newConf.isValid(), "Invalid new conf: %s", newConf);
// The new conf entry(will be stored in log manager) should be valid
Requires.requireTrue(new ConfigurationEntry(null, newConf, oldConf).isValid(), "Invalid conf entry: %s",
newConf);
if (this.state != State.STATE_LEADER) {
LOG.warn("Node {} refused configuration changing as the state={}.", getNodeId(), this.state);
if (done != null) {
final Status status = new Status();
if (this.state == State.STATE_TRANSFERRING) {
status.setError(RaftError.EBUSY, "Is transferring leadership.");
} else {
status.setError(RaftError.EPERM, "Not leader");
}
Utils.runClosureInThread(done, status);
}
return;
}
// check concurrent conf change
if (this.confCtx.isBusy()) {
LOG.warn("Node {} refused configuration concurrent changing.", getNodeId());
if (done != null) {
Utils.runClosureInThread(done, new Status(RaftError.EBUSY, "Doing another configuration change."));
}
return;
}
// Return immediately when the new peers equals to current configuration
if (this.conf.getConf().equals(newConf)) {
Utils.runClosureInThread(done);
return;
}
this.confCtx.start(oldConf, newConf, done);
}
示例24
@Override
public void addPeer(final PeerId peer, final Closure done) {
Requires.requireNonNull(peer, "Null peer");
this.writeLock.lock();
try {
Requires.requireTrue(!this.conf.getConf().contains(peer), "Peer already exists in current configuration");
final Configuration newConf = new Configuration(this.conf.getConf());
newConf.addPeer(peer);
unsafeRegisterConfChange(this.conf.getConf(), newConf, done);
} finally {
this.writeLock.unlock();
}
}
示例25
@Override
public void removePeer(final PeerId peer, final Closure done) {
Requires.requireNonNull(peer, "Null peer");
this.writeLock.lock();
try {
Requires.requireTrue(this.conf.getConf().contains(peer), "Peer not found in current configuration");
final Configuration newConf = new Configuration(this.conf.getConf());
newConf.removePeer(peer);
unsafeRegisterConfChange(this.conf.getConf(), newConf, done);
} finally {
this.writeLock.unlock();
}
}
示例26
@Override
public void changePeers(final Configuration newPeers, final Closure done) {
Requires.requireNonNull(newPeers, "Null new peers");
Requires.requireTrue(!newPeers.isEmpty(), "Empty new peers");
this.writeLock.lock();
try {
LOG.info("Node {} change peers from {} to {}.", getNodeId(), this.conf.getConf(), newPeers);
unsafeRegisterConfChange(this.conf.getConf(), newPeers, done);
} finally {
this.writeLock.unlock();
}
}
示例27
@Override
public void addLearners(final List<PeerId> learners, final Closure done) {
checkPeers(learners);
this.writeLock.lock();
try {
final Configuration newConf = new Configuration(this.conf.getConf());
for (final PeerId peer : learners) {
newConf.addLearner(peer);
}
unsafeRegisterConfChange(this.conf.getConf(), newConf, done);
} finally {
this.writeLock.unlock();
}
}
示例28
@Override
public void removeLearners(final List<PeerId> learners, final Closure done) {
checkPeers(learners);
this.writeLock.lock();
try {
final Configuration newConf = new Configuration(this.conf.getConf());
for (final PeerId peer : learners) {
newConf.removeLearner(peer);
}
unsafeRegisterConfChange(this.conf.getConf(), newConf, done);
} finally {
this.writeLock.unlock();
}
}
示例29
@Override
public void resetLearners(final List<PeerId> learners, final Closure done) {
checkPeers(learners);
this.writeLock.lock();
try {
final Configuration newConf = new Configuration(this.conf.getConf());
newConf.setLearners(new LinkedHashSet<>(learners));
unsafeRegisterConfChange(this.conf.getConf(), newConf, done);
} finally {
this.writeLock.unlock();
}
}
示例30
private void doSnapshot(final Closure done) {
if (this.snapshotExecutor != null) {
this.snapshotExecutor.doSnapshot(done);
} else {
if (done != null) {
final Status status = new Status(RaftError.EINVAL, "Snapshot is not supported");
Utils.runClosureInThread(done, status);
}
}
}