bk.mainWorkerPool.submitOrdered(ledgerId, new SafeRunnable() {
@Override
public void safeRun() {
final long prevLastEntryId;
final long prevLength;
final State prevState;
List<PendingAddOp> pendingAdds;
synchronized(LedgerHandle.this) {
// if the metadata is already closed, we don't need to proceed the process
// otherwise, it might end up encountering bad version error log messages when updating metadata
if (metadata.isClosed()) {
cb.closeComplete(BKException.Code.OK, LedgerHandle.this, ctx);
return;
}
prevState = metadata.getState();
prevLastEntryId = metadata.getLastEntryId();
prevLength = metadata.getLength();
// drain pending adds first
pendingAdds = drainPendingAddsToErrorOut();
// synchronized on LedgerHandle.this to ensure that
// lastAddPushed can not be updated after the metadata
// is closed.
metadata.setLength(length);
metadata.close(lastAddConfirmed);
lastAddPushed = lastAddConfirmed;
}
// error out all pending adds during closing, the callbacks shouldn't be
// running under any bk locks.
errorOutPendingAdds(rc, pendingAdds);
if (LOG.isDebugEnabled()) {
LOG.debug("Closing ledger: " + ledgerId + " at entryId: "
+ metadata.getLastEntryId() + " with this many bytes: " + metadata.getLength());
}
final class CloseCb extends OrderedSafeGenericCallback<Void> {
CloseCb() {
super(bk.mainWorkerPool, ledgerId);
}
@Override
public void safeOperationComplete(final int rc, Void result) {
if (rc == BKException.Code.MetadataVersionException) {
rereadMetadata(new OrderedSafeGenericCallback<LedgerMetadata>(bk.mainWorkerPool,
ledgerId) {
@Override
public void safeOperationComplete(int newrc, LedgerMetadata newMeta) {
if (newrc != BKException.Code.OK) {
LOG.error("Error reading new metadata from ledger " + ledgerId
+ " when closing, code=" + newrc);
cb.closeComplete(rc, LedgerHandle.this, ctx);
} else {
metadata.setState(prevState);
if (prevState.equals(State.CLOSED)) {
metadata.close(prevLastEntryId);
}
metadata.setLength(prevLength);
if (!metadata.isNewerThan(newMeta)