public static Entry create(long ledgerId, long entryId, ByteBuf data) { return EntryImpl.create(ledgerId, entryId, data); }
@Override public void asyncReadEntry(ReadHandle lh, long firstEntry, long lastEntry, boolean isSlowestReader, final ReadEntriesCallback callback, Object ctx) { lh.readAsync(firstEntry, lastEntry).whenComplete( (ledgerEntries, exception) -> { if (exception != null) { callback.readEntriesFailed(createManagedLedgerException(exception), ctx); return; } List<Entry> entries = Lists.newArrayList(); long totalSize = 0; try { for (LedgerEntry e : ledgerEntries) { // Insert the entries at the end of the list (they will be unsorted for now) EntryImpl entry = EntryImpl.create(e); entries.add(entry); totalSize += entry.getLength(); } } finally { ledgerEntries.close(); } mlFactoryMBean.recordCacheMiss(entries.size(), totalSize); ml.mbean.addReadEntriesSample(entries.size(), totalSize); callback.readEntriesComplete(entries, null); }); }
@Test(timeOut = 5000) void testReadMissingMultiple() throws Exception { ReadHandle lh = getLedgerHandle(); when(lh.getId()).thenReturn((long) 0); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache entryCache = cacheManager.getEntryCache(ml); byte[] data = new byte[10]; entryCache.insert(EntryImpl.create(0, 0, data)); entryCache.insert(EntryImpl.create(0, 2, data)); entryCache.insert(EntryImpl.create(0, 5, data)); entryCache.insert(EntryImpl.create(0, 8, data)); final CountDownLatch counter = new CountDownLatch(1); entryCache.asyncReadEntry(lh, 0, 9, false, new ReadEntriesCallback() { public void readEntriesComplete(List<Entry> entries, Object ctx) { assertEquals(entries.size(), 10); counter.countDown(); } public void readEntriesFailed(ManagedLedgerException exception, Object ctx) { Assert.fail("should not have failed"); } }, null); counter.await(); }
EntryImpl cacheEntry = EntryImpl.create(position, cachedData); cachedData.release(); if (entries.put(position, cacheEntry)) {
@Test(timeOut = 5000) void testReadMissingMiddle() throws Exception { ReadHandle lh = getLedgerHandle(); when(lh.getId()).thenReturn((long) 0); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache entryCache = cacheManager.getEntryCache(ml); byte[] data = new byte[10]; entryCache.insert(EntryImpl.create(0, 0, data)); entryCache.insert(EntryImpl.create(0, 1, data)); entryCache.insert(EntryImpl.create(0, 8, data)); entryCache.insert(EntryImpl.create(0, 9, data)); final CountDownLatch counter = new CountDownLatch(1); entryCache.asyncReadEntry(lh, 0, 9, false, new ReadEntriesCallback() { public void readEntriesComplete(List<Entry> entries, Object ctx) { assertEquals(entries.size(), 10); counter.countDown(); } public void readEntriesFailed(ManagedLedgerException exception, Object ctx) { Assert.fail("should not have failed"); } }, null); counter.await(); }
@Test void doubleInsert() throws Exception { ManagedLedgerFactoryConfig config = new ManagedLedgerFactoryConfig(); config.setMaxCacheSize(10); config.setCacheEvictionWatermark(0.8); factory = new ManagedLedgerFactoryImpl(bkc, bkc.getZkHandle(), config); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache cache1 = cacheManager.getEntryCache(ml1); assertEquals(cache1.insert(EntryImpl.create(1, 1, new byte[4])), true); assertEquals(cache1.insert(EntryImpl.create(1, 0, new byte[3])), true); assertEquals(cache1.getSize(), 7); assertEquals(cacheManager.getSize(), 7); assertEquals(cache1.insert(EntryImpl.create(1, 0, new byte[5])), false); assertEquals(cache1.getSize(), 7); assertEquals(cacheManager.getSize(), 7); }
@Test(timeOut = 5000) void testReadMissingBefore() throws Exception { ReadHandle lh = getLedgerHandle(); when(lh.getId()).thenReturn((long) 0); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache entryCache = cacheManager.getEntryCache(ml); byte[] data = new byte[10]; for (int i = 3; i < 10; i++) { entryCache.insert(EntryImpl.create(0, i, data)); } final CountDownLatch counter = new CountDownLatch(1); entryCache.asyncReadEntry(lh, 0, 9, false, new ReadEntriesCallback() { public void readEntriesComplete(List<Entry> entries, Object ctx) { assertEquals(entries.size(), 10); counter.countDown(); } public void readEntriesFailed(ManagedLedgerException exception, Object ctx) { Assert.fail("should not have failed"); } }, null); counter.await(); }
@Test(timeOut = 5000) void testReadMissingAfter() throws Exception { ReadHandle lh = getLedgerHandle(); when(lh.getId()).thenReturn((long) 0); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache entryCache = cacheManager.getEntryCache(ml); byte[] data = new byte[10]; for (int i = 0; i < 8; i++) { entryCache.insert(EntryImpl.create(0, i, data)); } final CountDownLatch counter = new CountDownLatch(1); entryCache.asyncReadEntry(lh, 0, 9, false, new ReadEntriesCallback() { public void readEntriesComplete(List<Entry> entries, Object ctx) { assertEquals(entries.size(), 10); counter.countDown(); } public void readEntriesFailed(ManagedLedgerException exception, Object ctx) { Assert.fail("should not have failed"); } }, null); counter.await(); }
@Test(timeOut = 5000) void testRead() throws Exception { ReadHandle lh = getLedgerHandle(); when(lh.getId()).thenReturn((long) 0); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache entryCache = cacheManager.getEntryCache(ml); byte[] data = new byte[10]; for (int i = 0; i < 10; i++) { entryCache.insert(EntryImpl.create(0, i, data)); } final CountDownLatch counter = new CountDownLatch(1); entryCache.asyncReadEntry(lh, 0, 9, false, new ReadEntriesCallback() { public void readEntriesComplete(List<Entry> entries, Object ctx) { assertEquals(entries.size(), 10); entries.forEach(e -> e.release()); counter.countDown(); } public void readEntriesFailed(ManagedLedgerException exception, Object ctx) { Assert.fail("should not have failed"); } }, null); counter.await(); // Verify no entries were read from bookkeeper verify(lh, never()).readAsync(anyLong(), anyLong()); }
@Test(timeOut = 5000) void testReadWithError() throws Exception { final ReadHandle lh = getLedgerHandle(); when(lh.getId()).thenReturn((long) 0); doAnswer((invocation) -> { CompletableFuture<LedgerEntries> future = new CompletableFuture<>(); future.completeExceptionally(new BKNoSuchLedgerExistsException()); return future; }).when(lh).readAsync(anyLong(), anyLong()); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache entryCache = cacheManager.getEntryCache(ml); byte[] data = new byte[10]; entryCache.insert(EntryImpl.create(0, 2, data)); final CountDownLatch counter = new CountDownLatch(1); entryCache.asyncReadEntry(lh, 0, 9, false, new ReadEntriesCallback() { public void readEntriesComplete(List<Entry> entries, Object ctx) { Assert.fail("should not complete"); } public void readEntriesFailed(ManagedLedgerException exception, Object ctx) { counter.countDown(); } }, null); counter.await(); }
@Test void cacheDisabled() throws Exception { ManagedLedgerFactoryConfig config = new ManagedLedgerFactoryConfig(); config.setMaxCacheSize(0); config.setCacheEvictionWatermark(0.8); factory = new ManagedLedgerFactoryImpl(bkc, bkc.getZkHandle(), config); EntryCacheManager cacheManager = factory.getEntryCacheManager(); EntryCache cache1 = cacheManager.getEntryCache(ml1); EntryCache cache2 = cacheManager.getEntryCache(ml2); assertTrue(cache1 instanceof EntryCacheManager.EntryCacheDisabled); assertTrue(cache2 instanceof EntryCacheManager.EntryCacheDisabled); cache1.insert(EntryImpl.create(1, 1, new byte[4])); cache1.insert(EntryImpl.create(1, 0, new byte[3])); assertEquals(cache1.getSize(), 0); assertEquals(cacheManager.getSize(), 0); cacheManager.mlFactoryMBean.refreshStats(1, TimeUnit.SECONDS); assertEquals(cacheManager.mlFactoryMBean.getCacheMaxSize(), 0); assertEquals(cacheManager.mlFactoryMBean.getCacheUsedSize(), 0); assertEquals(cacheManager.mlFactoryMBean.getCacheHitsRate(), 0.0); assertEquals(cacheManager.mlFactoryMBean.getCacheMissesRate(), 0.0); assertEquals(cacheManager.mlFactoryMBean.getCacheHitsThroughput(), 0.0); assertEquals(cacheManager.mlFactoryMBean.getNumberOfCacheEvictions(), 0); cache2.insert(EntryImpl.create(2, 0, new byte[1])); cache2.insert(EntryImpl.create(2, 1, new byte[1])); cache2.insert(EntryImpl.create(2, 2, new byte[1])); assertEquals(cache2.getSize(), 0); assertEquals(cacheManager.getSize(), 0); }
if (ml.hasActiveCursors()) { EntryImpl entry = EntryImpl.create(ledger.getId(), entryId, data);
EntryCache cache2 = cacheManager.getEntryCache(ml2); cache1.insert(EntryImpl.create(1, 1, new byte[4])); cache1.insert(EntryImpl.create(1, 0, new byte[3])); assertEquals(cacheManager.mlFactoryMBean.getNumberOfCacheEvictions(), 0); cache2.insert(EntryImpl.create(2, 0, new byte[1])); cache2.insert(EntryImpl.create(2, 1, new byte[1])); cache2.insert(EntryImpl.create(2, 2, new byte[1])); cache2.insert(EntryImpl.create(2, 3, new byte[1]));
public static Entry create(long ledgerId, long entryId, ByteBuf data) { return EntryImpl.create(ledgerId, entryId, data); }
public void readComplete(int rc, LedgerHandle lh, Enumeration<LedgerEntry> seq, Object bkctx) { if (rc != BKException.Code.OK) { callback.readEntriesFailed(new ManagedLedgerException(BKException.create(rc)), ctx); return; } List<Entry> entries = Lists.newArrayList(); long totalSize = 0; while (seq.hasMoreElements()) { // Insert the entries at the end of the list (they will be unsorted for now) LedgerEntry ledgerEntry = seq.nextElement(); EntryImpl entry = EntryImpl.create(ledgerEntry); ledgerEntry.getEntryBuffer().release(); entries.add(entry); totalSize += entry.getLength(); } mlFactoryMBean.recordCacheMiss(entries.size(), totalSize); ml.mbean.addReadEntriesSample(entries.size(), totalSize); callback.readEntriesComplete(entries, null); } }, null);
private static CompletableFuture<List<Entry>> readEntries(LedgerHandle lh, long from, long to) { CompletableFuture<Enumeration<LedgerEntry>> promise = new CompletableFuture<>(); lh.asyncReadEntries(from, to, (rc, _lh, seq, ctx) -> { if (rc != BKException.Code.OK) { promise.completeExceptionally(BKException.create(rc)); } else { promise.complete(seq); } }, null); return promise.thenApply( (seq) -> { List<Entry> entries = new ArrayList<Entry>(); while (seq.hasMoreElements()) { ByteBuf buf = seq.nextElement().getEntryBuffer(); try (RawMessage m = RawMessageImpl.deserializeFrom(buf)) { entries.add(EntryImpl.create(m.getMessageIdData().getLedgerId(), m.getMessageIdData().getEntryId(), m.getHeadersAndPayload())); } finally { buf.release(); } } return entries; }); }
@Override public void asyncReadEntry(ReadHandle lh, long firstEntry, long lastEntry, boolean isSlowestReader, final ReadEntriesCallback callback, Object ctx) { lh.readAsync(firstEntry, lastEntry).whenComplete( (ledgerEntries, exception) -> { if (exception != null) { callback.readEntriesFailed(createManagedLedgerException(exception), ctx); return; } List<Entry> entries = Lists.newArrayList(); long totalSize = 0; try { for (LedgerEntry e : ledgerEntries) { // Insert the entries at the end of the list (they will be unsorted for now) EntryImpl entry = EntryImpl.create(e); entries.add(entry); totalSize += entry.getLength(); } } finally { ledgerEntries.close(); } mlFactoryMBean.recordCacheMiss(entries.size(), totalSize); ml.mbean.addReadEntriesSample(entries.size(), totalSize); callback.readEntriesComplete(entries, null); }); }
if (ml.hasActiveCursors()) { EntryImpl entry = EntryImpl.create(ledger.getId(), entryId, data);