@Override public void close() { if (!this.closed.getAndSet(true)) { if (this.currentLedger != null) { try { Ledgers.close(this.currentLedger.handle); } catch (DurableDataLogException bkEx) { log.error("Unable to close LedgerHandle for Ledger {}.", this.currentLedger.handle.getId(), bkEx); } this.currentLedger = null; } } }
/** * Reliably retrieves the LastAddConfirmed for the Ledger with given LedgerId, by opening the Ledger in fencing mode * and getting the value. NOTE: this open-fences the Ledger which will effectively stop any writing action on it. * * @param ledgerId The Id of the Ledger to query. * @param bookKeeper A references to the BookKeeper client to use. * @param config Configuration to use. * @return The LastAddConfirmed for the given LedgerId. * @throws DurableDataLogException If an exception occurred. The causing exception is wrapped inside it. */ static long readLastAddConfirmed(long ledgerId, BookKeeper bookKeeper, BookKeeperConfig config) throws DurableDataLogException { LedgerHandle h = null; try { // Here we open the Ledger WITH recovery, to force BookKeeper to reconcile any appends that may have been // interrupted and not properly acked. Otherwise there is no guarantee we can get an accurate value for // LastAddConfirmed. h = openFence(ledgerId, bookKeeper, config); return h.getLastAddConfirmed(); } finally { if (h != null) { close(h); } } }
@Override public void close() { if (!this.closed.getAndSet(true)) { this.metricReporter.cancel(true); this.metrics.close(); this.rolloverProcessor.close(); this.writeProcessor.close(); // Close active ledger. WriteLedger writeLedger; synchronized (this.lock) { writeLedger = this.writeLedger; this.writeLedger = null; this.logMetadata = null; } // Close the write queue and cancel the pending writes. this.writes.close().forEach(w -> w.fail(new CancellationException("BookKeeperLog has been closed."), true)); if (writeLedger != null) { try { Ledgers.close(writeLedger.ledger); } catch (DurableDataLogException bkEx) { log.error("{}: Unable to close LedgerHandle for Ledger {}.", this.traceObjectId, writeLedger.ledger.getId(), bkEx); } } log.info("{}: Closed.", this.traceObjectId); } }
close(handle); log.info("{}: Fenced out Ledger {}.", traceObjectId, ledgerMetadata);
if (lastEntryId < address.getEntryId()) { Ledgers.close(ledger); this.currentLedger = new ReadLedger(metadata, ledger, null); return; if (previousLedger != null) { Ledgers.close(previousLedger.handle); Ledgers.close(ledger); close(); throw new DurableDataLogException("Error while reading from BookKeeper.", ex);
@Override public DurableDataLog.ReadItem getNext() throws DurableDataLogException { Exceptions.checkNotClosed(this.closed.get(), this); if (this.currentLedger == null) { // First time we call this. Locate the first ledger based on the metadata truncation address. We don't know // how many entries are in that first ledger, so open it anyway so we can figure out. openNextLedger(this.metadata.getNextAddress(this.metadata.getTruncationAddress(), Long.MAX_VALUE)); } while (this.currentLedger != null && (!this.currentLedger.canRead())) { // We have reached the end of the current ledger. Find next one, and skip over empty ledgers). val lastAddress = new LedgerAddress(this.currentLedger.metadata, this.currentLedger.handle.getLastAddConfirmed()); Ledgers.close(this.currentLedger.handle); openNextLedger(this.metadata.getNextAddress(lastAddress, this.currentLedger.handle.getLastAddConfirmed())); } // Try to read from the current reader. if (this.currentLedger == null || this.currentLedger.reader == null) { return null; } return new LogReader.ReadItem(this.currentLedger.reader.nextElement(), this.currentLedger.metadata); }
Ledgers.close(oldLedger); log.info("{}: Rollover: swapped ledger and metadata pointers (Old = {}, New = {}) and closed old ledger.", this.traceObjectId, oldLedger.getId(), newLedger.getId());