use of org.apache.bookkeeper.mledger.ManagedLedgerException.CursorAlreadyClosedException in project pulsar by yahoo.
the class ManagedCursorImpl method asyncReadEntriesOrWait.
@Override
public void asyncReadEntriesOrWait(int numberOfEntriesToRead, ReadEntriesCallback callback, Object ctx) {
checkArgument(numberOfEntriesToRead > 0);
if (STATE_UPDATER.get(this) == State.Closed) {
callback.readEntriesFailed(new CursorAlreadyClosedException("Cursor was already closed"), ctx);
return;
}
if (hasMoreEntries()) {
// If we have available entries, we can read them immediately
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] Read entries immediately", ledger.getName(), name);
}
asyncReadEntries(numberOfEntriesToRead, callback, ctx);
} else {
OpReadEntry op = OpReadEntry.create(this, PositionImpl.get(readPosition), numberOfEntriesToRead, callback, ctx);
if (!WAITING_READ_OP_UPDATER.compareAndSet(this, null, op)) {
callback.readEntriesFailed(new ManagedLedgerException("We can only have a single waiting callback"), ctx);
return;
}
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] Deferring retry of read at position {}", ledger.getName(), name, op.readPosition);
}
// Check again for new entries again in 10ms, then if still no entries are available register to be notified
ledger.getScheduledExecutor().schedule(safeRun(() -> {
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] Re-trying the read at position {}", ledger.getName(), name, op.readPosition);
}
if (!hasMoreEntries()) {
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] Still no entries available. Register for notification", ledger.getName(), name);
}
// Let the managed ledger know we want to be notified whenever a new entry is published
ledger.waitingCursors.add(this);
} else {
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] Skip notification registering since we do have entries available", ledger.getName(), name);
}
}
// checked and the time we've asked to be notified by managed ledger
if (hasMoreEntries()) {
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] Found more entries", ledger.getName(), name);
}
// Try to cancel the notification request
if (WAITING_READ_OP_UPDATER.compareAndSet(this, op, null)) {
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] Cancelled notification and scheduled read at {}", ledger.getName(), name, op.readPosition);
}
PENDING_READ_OPS_UPDATER.incrementAndGet(this);
ledger.asyncReadEntries(op);
} else {
if (log.isDebugEnabled()) {
log.debug("[{}] [{}] notification was already cancelled", ledger.getName(), name);
}
}
}
}), 10, TimeUnit.MILLISECONDS);
}
}
use of org.apache.bookkeeper.mledger.ManagedLedgerException.CursorAlreadyClosedException in project pulsar by yahoo.
the class ReplicatorTest method testCloseReplicatorStartProducer.
/**
* It verifies that PersistentReplicator considers CursorAlreadyClosedException as non-retriable-read exception and
* it should closed the producer as cursor is already closed because replicator is already deleted.
*
* @throws Exception
*/
@Test(timeOut = 5000)
public void testCloseReplicatorStartProducer() throws Exception {
DestinationName dest = DestinationName.get("persistent://pulsar/global/ns1/closeCursor");
// Producer on r1
MessageProducer producer1 = new MessageProducer(url1, dest);
// Consumer on r1
MessageConsumer consumer1 = new MessageConsumer(url1, dest);
// Consumer on r2
MessageConsumer consumer2 = new MessageConsumer(url2, dest);
// Replicator for r1 -> r2
PersistentTopic topic = (PersistentTopic) pulsar1.getBrokerService().getTopicReference(dest.toString());
PersistentReplicator replicator = topic.getPersistentReplicator("r2");
// close the cursor
Field cursorField = PersistentReplicator.class.getDeclaredField("cursor");
cursorField.setAccessible(true);
ManagedCursor cursor = (ManagedCursor) cursorField.get(replicator);
cursor.close();
// try to read entries
CountDownLatch latch = new CountDownLatch(1);
producer1.produce(10);
cursor.asyncReadEntriesOrWait(10, new ReadEntriesCallback() {
@Override
public void readEntriesComplete(List<Entry> entries, Object ctx) {
latch.countDown();
fail("it should have been failed");
}
@Override
public void readEntriesFailed(ManagedLedgerException exception, Object ctx) {
latch.countDown();
assertTrue(exception instanceof CursorAlreadyClosedException);
}
}, null);
// replicator-readException: cursorAlreadyClosed
replicator.readEntriesFailed(new CursorAlreadyClosedException("Cursor already closed exception"), null);
// wait replicator producer to be closed
Thread.sleep(1000);
// Replicator producer must be closed
Field producerField = PersistentReplicator.class.getDeclaredField("producer");
producerField.setAccessible(true);
ProducerImpl replicatorProducer = (ProducerImpl) producerField.get(replicator);
assertEquals(replicatorProducer, null);
producer1.close();
consumer1.close();
consumer2.close();
}
Aggregations