/** * Write Processor main loop. This method is not thread safe and should only be invoked as part of the Write Processor. */ private void processWritesSync() { if (this.closed.get()) { // BookKeeperLog is closed. No point in trying anything else. return; } if (getWriteLedger().ledger.isClosed()) { // Current ledger is closed. Execute the rollover processor to safely create a new ledger. This will reinvoke // the write processor upon finish, so the writes can be reattempted. this.rolloverProcessor.runAsync(); } else if (!processPendingWrites() && !this.closed.get()) { // We were not able to complete execution of all writes. Try again. this.writeProcessor.runAsync(); } }
/** * Collects an ordered list of Writes to execute to BookKeeper. * * @return The list of Writes to execute. */ private List<Write> getWritesToExecute() { // Calculate how much estimated space there is in the current ledger. final long maxTotalSize = this.config.getBkLedgerMaxSize() - getWriteLedger().ledger.getLength(); // Get the writes to execute from the queue. List<Write> toExecute = this.writes.getWritesToExecute(maxTotalSize); // Check to see if any writes executed on closed ledgers, in which case they either need to be failed (if deemed // appropriate, or retried). if (handleClosedLedgers(toExecute)) { // If any changes were made to the Writes in the list, re-do the search to get a more accurate list of Writes // to execute (since some may have changed Ledgers, more writes may not be eligible for execution). toExecute = this.writes.getWritesToExecute(maxTotalSize); } return toExecute; }
WriteLedger currentLedger = getWriteLedger(); Map<Long, Long> lastAddsConfirmed = new HashMap<>(); boolean anythingChanged = false;
val l = getWriteLedger().ledger; if (!l.isClosed() && l.getLength() < this.config.getBkLedgerMaxSize()) {
@Override public CompletableFuture<LogAddress> append(ArrayView data, Duration timeout) { ensurePreconditions(); long traceId = LoggerHelpers.traceEnterWithContext(log, this.traceObjectId, "append", data.getLength()); if (data.getLength() > getMaxAppendLength()) { return Futures.failedFuture(new WriteTooLongException(data.getLength(), getMaxAppendLength())); } Timer timer = new Timer(); // Queue up the write. CompletableFuture<LogAddress> result = new CompletableFuture<>(); this.writes.add(new Write(data, getWriteLedger(), result)); // Trigger Write Processor. this.writeProcessor.runAsync(); // Post append tasks. We do not need to wait for these to happen before returning the call. result.whenCompleteAsync((address, ex) -> { if (ex != null) { handleWriteException(ex); } else { // Update metrics and take care of other logging tasks. this.metrics.writeCompleted(timer.getElapsed()); LoggerHelpers.traceLeave(log, this.traceObjectId, "append", traceId, data.getLength(), address); } }, this.executorService); return result; }