use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.
the class BookieJournalForceTest method testAckBeforeSync.
@Test
public void testAckBeforeSync() throws Exception {
File journalDir = tempDir.newFolder();
Bookie.checkDirectoryStructure(Bookie.getCurrentDirectory(journalDir));
ServerConfiguration conf = TestBKConfiguration.newServerConfiguration();
conf.setJournalDirName(journalDir.getPath()).setZkServers(null);
JournalChannel jc = spy(new JournalChannel(journalDir, 1));
whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
// machinery to suspend ForceWriteThread
CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
journal.start();
LogMark lastLogMarkBeforeWrite = journal.getLastLogMark().markLog().getCurMark();
CountDownLatch latch = new CountDownLatch(1);
long ledgerId = 1;
long entryId = 0;
journal.logAddEntry(ledgerId, entryId, DATA, true, /* ackBeforeSync */
new WriteCallback() {
@Override
public void writeComplete(int rc, long ledgerId, long entryId, BookieSocketAddress addr, Object ctx) {
latch.countDown();
}
}, null);
// logAddEntry should complete even if ForceWriteThread is suspended
latch.await(20, TimeUnit.SECONDS);
// in constructor of JournalChannel we are calling forceWrite(true) but it is not tracked by PowerMock
// because the 'spy' is applied only on return from the constructor
verify(jc, times(0)).forceWrite(true);
// we are never calling forceWrite
verify(jc, times(0)).forceWrite(false);
// verify that log marker did not advance
LastLogMark lastLogMarkAfterForceWrite = journal.getLastLogMark();
assertEquals(0, lastLogMarkAfterForceWrite.getCurMark().compare(lastLogMarkBeforeWrite));
// let the forceWriteThread exit
forceWriteThreadSuspendedLatch.countDown();
journal.shutdown();
}
use of org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback in project bookkeeper by apache.
the class ParallelLedgerRecoveryTest method testRecoveryOnEntryGap.
@Test
public void testRecoveryOnEntryGap() throws Exception {
byte[] passwd = "recovery-on-entry-gap".getBytes(UTF_8);
LedgerHandle lh = bkc.createLedger(1, 1, 1, DigestType.CRC32, passwd);
for (int i = 0; i < 10; i++) {
lh.addEntry(("recovery-on-entry-gap-" + i).getBytes(UTF_8));
}
// simulate ledger writer failure on concurrent writes causing gaps
long entryId = 14;
long lac = 8;
byte[] data = "recovery-on-entry-gap-gap".getBytes(UTF_8);
ByteBufList toSend = lh.macManager.computeDigestAndPackageForSending(entryId, lac, lh.getLength() + 100, Unpooled.wrappedBuffer(data, 0, data.length));
final CountDownLatch addLatch = new CountDownLatch(1);
final AtomicBoolean addSuccess = new AtomicBoolean(false);
LOG.info("Add entry {} with lac = {}", entryId, lac);
lh.bk.getBookieClient().addEntry(lh.metadata.currentEnsemble.get(0), lh.getId(), lh.ledgerKey, entryId, toSend, new WriteCallback() {
@Override
public void writeComplete(int rc, long ledgerId, long entryId, BookieSocketAddress addr, Object ctx) {
addSuccess.set(BKException.Code.OK == rc);
addLatch.countDown();
}
}, 0, BookieProtocol.FLAG_NONE);
addLatch.await();
assertTrue("add entry 14 should succeed", addSuccess.get());
ClientConfiguration newConf = new ClientConfiguration();
newConf.addConfiguration(baseClientConf);
newConf.setEnableParallelRecoveryRead(true);
newConf.setRecoveryReadBatchSize(10);
BookKeeper newBk = new BookKeeper(newConf);
final LedgerHandle recoverLh = newBk.openLedgerNoRecovery(lh.getId(), DigestType.CRC32, passwd);
assertEquals("wrong lac found", 8L, recoverLh.getLastAddConfirmed());
final CountDownLatch recoverLatch = new CountDownLatch(1);
final AtomicLong newLac = new AtomicLong(-1);
final AtomicBoolean isMetadataClosed = new AtomicBoolean(false);
final AtomicInteger numSuccessCalls = new AtomicInteger(0);
final AtomicInteger numFailureCalls = new AtomicInteger(0);
recoverLh.recover(new GenericCallback<Void>() {
@Override
public void operationComplete(int rc, Void result) {
if (BKException.Code.OK == rc) {
newLac.set(recoverLh.getLastAddConfirmed());
isMetadataClosed.set(recoverLh.getLedgerMetadata().isClosed());
numSuccessCalls.incrementAndGet();
} else {
numFailureCalls.incrementAndGet();
}
recoverLatch.countDown();
}
});
recoverLatch.await();
assertEquals("wrong lac found", 9L, newLac.get());
assertTrue("metadata isn't closed after recovery", isMetadataClosed.get());
Thread.sleep(5000);
assertEquals("recovery callback should be triggered only once", 1, numSuccessCalls.get());
assertEquals("recovery callback should be triggered only once", 0, numFailureCalls.get());
}
Aggregations