use of org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback in project pulsar by yahoo.
the class ManagedLedgerErrorsTest method recoverLongTimeAfterMultipleWriteErrors.
@Test
public void recoverLongTimeAfterMultipleWriteErrors() throws Exception {
ManagedLedgerImpl ledger = (ManagedLedgerImpl) factory.open("recoverLongTimeAfterMultipleWriteErrors");
ManagedCursor cursor = ledger.openCursor("c1");
bkc.failNow(BKException.Code.BookieHandleNotAvailableException, BKException.Code.BookieHandleNotAvailableException);
CountDownLatch counter = new CountDownLatch(2);
AtomicReference<ManagedLedgerException> ex = new AtomicReference<>();
// Write 2 entries, both should fail the first time and get re-tried internally in a new ledger
AddEntryCallback cb = new AddEntryCallback() {
@Override
public void addComplete(Position position, Object ctx) {
counter.countDown();
}
@Override
public void addFailed(ManagedLedgerException exception, Object ctx) {
log.warn("Error in write", exception);
ex.set(exception);
counter.countDown();
}
};
ledger.asyncAddEntry("entry-1".getBytes(), cb, null);
ledger.asyncAddEntry("entry-2".getBytes(), cb, null);
counter.await();
assertNull(ex.get());
assertEquals(cursor.getNumberOfEntriesInBacklog(), 2);
// Ensure that we are only creating one new ledger
// even when there are multiple (here, 2) add entry failed ops
assertEquals(ledger.getLedgersInfoAsList().size(), 1);
ledger.addEntry("entry-3".getBytes());
List<Entry> entries = cursor.readEntries(10);
assertEquals(entries.size(), 3);
assertEquals(new String(entries.get(0).getData()), "entry-1");
assertEquals(new String(entries.get(1).getData()), "entry-2");
assertEquals(new String(entries.get(2).getData()), "entry-3");
entries.forEach(e -> e.release());
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback in project pulsar by yahoo.
the class PersistentTopicTest method testPublishMessageMLFailure.
@Test
public void testPublishMessageMLFailure() throws Exception {
final String successTopicName = "persistent://prop/use/ns-abc/successTopic";
final ManagedLedger ledgerMock = mock(ManagedLedger.class);
doReturn(new ArrayList<Object>()).when(ledgerMock).getCursors();
PersistentTopic topic = new PersistentTopic(successTopicName, ledgerMock, brokerService);
MessageMetadata.Builder messageMetadata = MessageMetadata.newBuilder();
messageMetadata.setPublishTime(System.currentTimeMillis());
messageMetadata.setProducerName("prod-name");
messageMetadata.setSequenceId(1);
ByteBuf payload = Unpooled.wrappedBuffer("content".getBytes());
final CountDownLatch latch = new CountDownLatch(1);
// override asyncAddEntry callback to return error
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
((AddEntryCallback) invocationOnMock.getArguments()[1]).addFailed(new ManagedLedgerException("Managed ledger failure"), invocationOnMock.getArguments()[2]);
return null;
}
}).when(ledgerMock).asyncAddEntry(any(ByteBuf.class), any(AddEntryCallback.class), anyObject());
topic.publishMessage(payload, (exception, ledgerId, entryId) -> {
if (exception == null) {
fail("publish should have failed");
} else {
latch.countDown();
}
});
assertTrue(latch.await(1, TimeUnit.SECONDS));
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback in project incubator-pulsar by apache.
the class ManagedLedgerImpl method addEntry.
@Override
public Position addEntry(byte[] data, int offset, int length) throws InterruptedException, ManagedLedgerException {
final CountDownLatch counter = new CountDownLatch(1);
// position
class Result {
ManagedLedgerException status = null;
Position position = null;
}
final Result result = new Result();
asyncAddEntry(data, offset, length, new AddEntryCallback() {
@Override
public void addComplete(Position position, Object ctx) {
result.position = position;
counter.countDown();
}
@Override
public void addFailed(ManagedLedgerException exception, Object ctx) {
result.status = exception;
counter.countDown();
}
}, null);
counter.await();
if (result.status != null) {
log.error("[{}] Error adding entry", name, result.status);
throw result.status;
}
return result.position;
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback in project incubator-pulsar by apache.
the class OpAddEntry method closeComplete.
@Override
public void closeComplete(int rc, LedgerHandle lh, Object ctx) {
checkArgument(ledger.getId() == lh.getId(), "ledgerId %s doesn't match with acked ledgerId %s", ledger.getId(), lh.getId());
if (rc == BKException.Code.OK) {
log.debug("Successfuly closed ledger {}", lh.getId());
} else {
log.warn("Error when closing ledger {}. Status={}", lh.getId(), BKException.getMessage(rc));
}
ml.ledgerClosed(lh);
updateLatency();
AddEntryCallback cb = callbackUpdater.getAndSet(this, null);
if (cb != null) {
cb.addComplete(PositionImpl.get(lh.getId(), entryId), ctx);
ml.notifyCursors();
this.recycle();
}
}
use of org.apache.bookkeeper.mledger.AsyncCallbacks.AddEntryCallback in project incubator-pulsar by apache.
the class ManagedLedgerTest method testBacklogCursor.
@Test
public void testBacklogCursor() throws Exception {
ManagedLedgerImpl ledger = (ManagedLedgerImpl) factory.open("cache_backlog_ledger");
final long maxMessageCacheRetentionTimeMillis = 100;
Field field = ManagedLedgerImpl.class.getDeclaredField("maxMessageCacheRetentionTimeMillis");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(ledger, maxMessageCacheRetentionTimeMillis);
Field backlogThresholdField = ManagedLedgerImpl.class.getDeclaredField("maxActiveCursorBacklogEntries");
backlogThresholdField.setAccessible(true);
final long maxActiveCursorBacklogEntries = (long) backlogThresholdField.get(ledger);
// Open Cursor also adds cursor into activeCursor-container
ManagedCursor cursor1 = ledger.openCursor("c1");
ManagedCursor cursor2 = ledger.openCursor("c2");
final int totalBacklogSizeEntries = (int) maxActiveCursorBacklogEntries;
CountDownLatch latch = new CountDownLatch(totalBacklogSizeEntries);
for (int i = 0; i < totalBacklogSizeEntries + 1; i++) {
// 5 bytes
String content = "entry";
ByteBuf entry = getMessageWithMetadata(content.getBytes());
ledger.asyncAddEntry(entry, new AddEntryCallback() {
@Override
public void addComplete(Position position, Object ctx) {
latch.countDown();
entry.release();
}
@Override
public void addFailed(ManagedLedgerException exception, Object ctx) {
latch.countDown();
entry.release();
}
}, null);
}
latch.await();
// Verify: cursors are active as :haven't started deactivateBacklogCursor scan
assertTrue(cursor1.isActive());
assertTrue(cursor2.isActive());
// it allows message to be older enough to be considered in backlog
Thread.sleep(maxMessageCacheRetentionTimeMillis * 2);
// deactivate backlog cursors
ledger.checkBackloggedCursors();
Thread.sleep(100);
// both cursors have to be inactive
assertFalse(cursor1.isActive());
assertFalse(cursor2.isActive());
// read entries so, cursor1 reaches maxBacklog threshold again to be active again
List<Entry> entries1 = cursor1.readEntries(50);
for (Entry entry : entries1) {
log.info("Read entry. Position={} Content='{}'", entry.getPosition(), new String(entry.getData()));
entry.release();
}
// activate cursors which caught up maxbacklog threshold
ledger.checkBackloggedCursors();
// verify: cursor1 has consumed messages so, under maxBacklog threshold => active
assertTrue(cursor1.isActive());
// verify: cursor2 has not consumed messages so, above maxBacklog threshold => inactive
assertFalse(cursor2.isActive());
ledger.close();
}
Aggregations