use of org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntryCallback in project pulsar by yahoo.
the class ManagedLedgerImpl method checkBackloggedCursors.
@Override
public void checkBackloggedCursors() {
// activate caught up cursors
cursors.forEach(cursor -> {
if (cursor.getNumberOfEntries() < maxActiveCursorBacklogEntries) {
cursor.setActive();
}
});
// deactivate backlog cursors
Iterator<ManagedCursor> cursors = activeCursors.iterator();
while (cursors.hasNext()) {
ManagedCursor cursor = cursors.next();
long backlogEntries = cursor.getNumberOfEntries();
if (backlogEntries > maxActiveCursorBacklogEntries) {
PositionImpl readPosition = (PositionImpl) cursor.getReadPosition();
readPosition = isValidPosition(readPosition) ? readPosition : getNextValidPosition(readPosition);
if (readPosition == null) {
if (log.isDebugEnabled()) {
log.debug("[{}] Couldn't find valid read position [{}] {}", name, cursor.getName(), cursor.getReadPosition());
}
continue;
}
try {
asyncReadEntry(readPosition, new ReadEntryCallback() {
@Override
public void readEntryFailed(ManagedLedgerException e, Object ctx) {
log.warn("[{}] Failed while reading entries on [{}] {}", name, cursor.getName(), e.getMessage(), e);
}
@Override
public void readEntryComplete(Entry entry, Object ctx) {
MessageMetadata msgMetadata = null;
try {
msgMetadata = Commands.parseMessageMetadata(entry.getDataBuffer());
long msgTimeSincePublish = (System.currentTimeMillis() - msgMetadata.getPublishTime());
if (msgTimeSincePublish > maxMessageCacheRetentionTimeMillis) {
cursor.setInactive();
}
} finally {
if (msgMetadata != null) {
msgMetadata.recycle();
}
entry.release();
}
}
}, null);
} catch (Exception e) {
log.warn("[{}] Failed while reading entries from cache on [{}] {}", name, cursor.getName(), e.getMessage(), e);
}
}
}
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntryCallback in project pulsar by yahoo.
the class ManagedCursorImpl method getNthEntry.
@Override
public Entry getNthEntry(int N, IndividualDeletedEntries deletedEntries) throws InterruptedException, ManagedLedgerException {
final CountDownLatch counter = new CountDownLatch(1);
class Result {
ManagedLedgerException exception = null;
Entry entry = null;
}
final Result result = new Result();
asyncGetNthEntry(N, deletedEntries, new ReadEntryCallback() {
@Override
public void readEntryFailed(ManagedLedgerException exception, Object ctx) {
result.exception = exception;
counter.countDown();
}
@Override
public void readEntryComplete(Entry entry, Object ctx) {
result.entry = entry;
counter.countDown();
}
}, null);
counter.await();
if (result.exception != null)
throw result.exception;
return result.entry;
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntryCallback in project pulsar by yahoo.
the class EntryCacheImpl method asyncReadEntry.
@Override
public void asyncReadEntry(LedgerHandle lh, PositionImpl position, final ReadEntryCallback callback, final Object ctx) {
if (log.isDebugEnabled()) {
log.debug("[{}] Reading entry ledger {}: {}", ml.getName(), lh.getId(), position.getEntryId());
}
EntryImpl entry = entries.get(position);
if (entry != null) {
EntryImpl cachedEntry = new EntryImpl(entry);
entry.release();
manager.mlFactoryMBean.recordCacheHit(cachedEntry.getLength());
callback.readEntryComplete(cachedEntry, ctx);
} else {
ReadCallback readCallback = (rc, ledgerHandle, sequence, obj) -> {
if (rc != BKException.Code.OK) {
ml.invalidateLedgerHandle(ledgerHandle, rc);
callback.readEntryFailed(new ManagedLedgerException(BKException.create(rc)), obj);
return;
}
if (sequence.hasMoreElements()) {
EntryImpl returnEntry = new EntryImpl(sequence.nextElement());
manager.mlFactoryMBean.recordCacheMiss(1, returnEntry.getLength());
ml.mbean.addReadEntriesSample(1, returnEntry.getLength());
callback.readEntryComplete(returnEntry, obj);
} else {
// got an empty sequence
callback.readEntryFailed(new ManagedLedgerException("Could not read given position"), obj);
}
};
lh.asyncReadEntries(position.getEntryId(), position.getEntryId(), readCallback, ctx);
}
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntryCallback in project pulsar by yahoo.
the class PersistentReplicator method peekNthMessage.
public CompletableFuture<Entry> peekNthMessage(int messagePosition) {
CompletableFuture<Entry> future = new CompletableFuture<>();
if (log.isDebugEnabled()) {
log.debug("[{}][{} -> {}] Getting message at position {}", topicName, localCluster, remoteCluster, messagePosition);
}
cursor.asyncGetNthEntry(messagePosition, IndividualDeletedEntries.Exclude, new ReadEntryCallback() {
@Override
public void readEntryFailed(ManagedLedgerException exception, Object ctx) {
future.completeExceptionally(exception);
}
@Override
public void readEntryComplete(Entry entry, Object ctx) {
future.complete(entry);
}
}, null);
return future;
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntryCallback in project incubator-pulsar by apache.
the class ManagedCursorImpl method asyncReplayEntries.
/**
* Async replays given positions: a. before reading it filters out already-acked messages b. reads remaining entries
* async and gives it to given ReadEntriesCallback c. returns all already-acked messages which are not replayed so,
* those messages can be removed by caller(Dispatcher)'s replay-list and it won't try to replay it again
*/
@Override
public Set<? extends Position> asyncReplayEntries(final Set<? extends Position> positions, ReadEntriesCallback callback, Object ctx) {
List<Entry> entries = Lists.newArrayListWithExpectedSize(positions.size());
if (positions.isEmpty()) {
callback.readEntriesComplete(entries, ctx);
}
// filters out messages which are already acknowledged
Set<Position> alreadyAcknowledgedPositions = Sets.newHashSet();
lock.readLock().lock();
try {
positions.stream().filter(position -> individualDeletedMessages.contains((PositionImpl) position) || ((PositionImpl) position).compareTo(markDeletePosition) < 0).forEach(alreadyAcknowledgedPositions::add);
} finally {
lock.readLock().unlock();
}
final int totalValidPositions = positions.size() - alreadyAcknowledgedPositions.size();
final AtomicReference<ManagedLedgerException> exception = new AtomicReference<>();
ReadEntryCallback cb = new ReadEntryCallback() {
int pendingCallbacks = totalValidPositions;
@Override
public synchronized void readEntryComplete(Entry entry, Object ctx) {
if (exception.get() != null) {
// if there is already a failure for a different position, we should release the entry straight away
// and not add it to the list
entry.release();
if (--pendingCallbacks == 0) {
callback.readEntriesFailed(exception.get(), ctx);
}
} else {
entries.add(entry);
if (--pendingCallbacks == 0) {
callback.readEntriesComplete(entries, ctx);
}
}
}
@Override
public synchronized void readEntryFailed(ManagedLedgerException mle, Object ctx) {
log.warn("[{}][{}] Error while replaying entries", ledger.getName(), name, mle);
if (exception.compareAndSet(null, mle)) {
// release the entries just once, any further read success will release the entry straight away
entries.forEach(Entry::release);
}
if (--pendingCallbacks == 0) {
callback.readEntriesFailed(exception.get(), ctx);
}
}
};
positions.stream().filter(position -> !alreadyAcknowledgedPositions.contains(position)).forEach(p -> ledger.asyncReadEntry((PositionImpl) p, cb, ctx));
return alreadyAcknowledgedPositions;
}
Aggregations