Search in sources :

Example 1 with CursorAlreadyClosedException

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);
    }
}
Also used : ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) CursorAlreadyClosedException(org.apache.bookkeeper.mledger.ManagedLedgerException.CursorAlreadyClosedException)

Example 2 with CursorAlreadyClosedException

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();
}
Also used : ReadEntriesCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntriesCallback) PersistentReplicator(com.yahoo.pulsar.broker.service.persistent.PersistentReplicator) CountDownLatch(java.util.concurrent.CountDownLatch) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) Field(java.lang.reflect.Field) ProducerImpl(com.yahoo.pulsar.client.impl.ProducerImpl) Entry(org.apache.bookkeeper.mledger.Entry) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) PersistentTopic(com.yahoo.pulsar.broker.service.persistent.PersistentTopic) DestinationName(com.yahoo.pulsar.common.naming.DestinationName) CursorAlreadyClosedException(org.apache.bookkeeper.mledger.ManagedLedgerException.CursorAlreadyClosedException) Test(org.testng.annotations.Test)

Aggregations

ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)2 CursorAlreadyClosedException (org.apache.bookkeeper.mledger.ManagedLedgerException.CursorAlreadyClosedException)2 PersistentReplicator (com.yahoo.pulsar.broker.service.persistent.PersistentReplicator)1 PersistentTopic (com.yahoo.pulsar.broker.service.persistent.PersistentTopic)1 ProducerImpl (com.yahoo.pulsar.client.impl.ProducerImpl)1 DestinationName (com.yahoo.pulsar.common.naming.DestinationName)1 Field (java.lang.reflect.Field)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ReadEntriesCallback (org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntriesCallback)1 Entry (org.apache.bookkeeper.mledger.Entry)1 ManagedCursor (org.apache.bookkeeper.mledger.ManagedCursor)1 Test (org.testng.annotations.Test)1