use of com.alipay.sofa.jraft.entity.ReadIndexStatus in project sofa-jraft by sofastack.
the class ReadOnlyServiceTest method testOnApplied.
@Test
public void testOnApplied() throws Exception {
final ArrayList<ReadIndexState> states = new ArrayList<>();
final byte[] reqContext = TestUtils.getRandomBytes();
final CountDownLatch latch = new CountDownLatch(1);
final ReadIndexState state = new ReadIndexState(new Bytes(reqContext), new ReadIndexClosure() {
@Override
public void run(final Status status, final long index, final byte[] reqCtx) {
assertTrue(status.isOk());
assertEquals(index, 1);
assertArrayEquals(reqCtx, reqContext);
latch.countDown();
}
}, Utils.monotonicMs());
state.setIndex(1);
states.add(state);
final ReadIndexStatus readIndexStatus = new ReadIndexStatus(states, null, 1);
this.readOnlyServiceImpl.getPendingNotifyStatus().put(1L, Arrays.asList(readIndexStatus));
this.readOnlyServiceImpl.onApplied(2);
latch.await();
assertTrue(this.readOnlyServiceImpl.getPendingNotifyStatus().isEmpty());
}
use of com.alipay.sofa.jraft.entity.ReadIndexStatus in project sofa-jraft by sofastack.
the class ReadOnlyServiceImpl method resetPendingStatusError.
private void resetPendingStatusError(final Status st) {
this.lock.lock();
try {
final Iterator<List<ReadIndexStatus>> it = this.pendingNotifyStatus.values().iterator();
while (it.hasNext()) {
final List<ReadIndexStatus> statuses = it.next();
for (final ReadIndexStatus status : statuses) {
reportError(status, st);
}
it.remove();
}
} finally {
this.lock.unlock();
}
}
use of com.alipay.sofa.jraft.entity.ReadIndexStatus in project sofa-jraft by sofastack.
the class ReadOnlyServiceImpl method onApplied.
/**
* Called when lastAppliedIndex updates.
*
* @param appliedIndex applied index
*/
@Override
public void onApplied(final long appliedIndex) {
// TODO reuse pendingStatuses list?
List<ReadIndexStatus> pendingStatuses = null;
this.lock.lock();
try {
if (this.pendingNotifyStatus.isEmpty()) {
return;
}
// Find all statuses that log index less than or equal to appliedIndex.
final Map<Long, List<ReadIndexStatus>> statuses = this.pendingNotifyStatus.headMap(appliedIndex, true);
if (statuses != null) {
pendingStatuses = new ArrayList<>(statuses.size() << 1);
final Iterator<Map.Entry<Long, List<ReadIndexStatus>>> it = statuses.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<Long, List<ReadIndexStatus>> entry = it.next();
pendingStatuses.addAll(entry.getValue());
// Remove the entry from statuses, it will also be removed in pendingNotifyStatus.
it.remove();
}
}
/*
* Remaining pending statuses are notified by error if it is presented.
* When the node is in error state, consider following situations:
* 1. If commitIndex > appliedIndex, then all pending statuses should be notified by error status.
* 2. When commitIndex == appliedIndex, there will be no more pending statuses.
*/
if (this.error != null) {
resetPendingStatusError(this.error.getStatus());
}
} finally {
this.lock.unlock();
if (pendingStatuses != null && !pendingStatuses.isEmpty()) {
for (final ReadIndexStatus status : pendingStatuses) {
notifySuccess(status);
}
}
}
}
Aggregations