/** * Fences a ledger. From this point on, clients will be unable to write to this ledger. Only * recoveryAddEntry will be able to add entries to the ledger. This method is idempotent. Once a * ledger is fenced, it can never be unfenced. Fencing a fenced ledger has no effect. */ public SettableFuture<Boolean> fenceLedger(long ledgerId, byte[] masterKey) throws IOException, BookieException { LedgerDescriptor handle = handles.getHandle(ledgerId, masterKey); boolean success; synchronized (handle) { success = handle.setFenced(); } if (success) { // fenced first time, we should add the key to journal ensure we can rebuild ByteBuffer bb = ByteBuffer.allocate(8 + 8); bb.putLong(ledgerId); bb.putLong(METAENTRY_ID_FENCE_KEY); bb.flip(); FutureWriteCallback fwc = new FutureWriteCallback(); LOG.debug("record fenced state for ledger {} in journal.", ledgerId); journal.logAddEntry(bb, fwc, null); return fwc.getResult(); } else { // already fenced SettableFuture<Boolean> successFuture = SettableFuture.create(); successFuture.set(true); return successFuture; } }
public long readLastAddConfirmed(long ledgerId) throws IOException { long requestNanos = MathUtils.nowInNano(); boolean success = false; try { LedgerDescriptor handle = handles.getReadOnlyHandle(ledgerId); long lac = handle.getLastAddConfirmed(); success = true; return lac; } finally { long elapsedMicros = MathUtils.elapsedMicroSec(requestNanos); if (success) { readLastConfirmedStats.registerSuccessfulEvent(elapsedMicros); } else { readLastConfirmedStats.registerFailedEvent(elapsedMicros); } } }
public ByteBuffer readEntry(long ledgerId, long entryId) throws IOException, NoLedgerException { long requestNanos = MathUtils.nowInNano(); boolean success = false; try { LedgerDescriptor handle = handles.getReadOnlyHandle(ledgerId); LOG.trace("Reading {}@{}", entryId, ledgerId); ByteBuffer data = handle.readEntry(entryId); success = true; return data; } finally { long elapsedMicros = MathUtils.elapsedMicroSec(requestNanos); if (success) { readEntryStats.registerSuccessfulEvent(elapsedMicros); } else { readEntryStats.registerFailedEvent(elapsedMicros); } } }
/** * Retrieve the ledger descriptor for the ledger which entry should be added to. The * LedgerDescriptor returned from this method should be eventually freed with #putHandle(). * * @throws BookieException if masterKey does not match the master key of the ledger */ private LedgerDescriptor getLedgerForEntry(ByteBuffer entry, byte[] masterKey) throws IOException, BookieException { long ledgerId = entry.getLong(); LedgerDescriptor l = handles.getHandle(ledgerId, masterKey); if (!masterKeyCache.containsKey(ledgerId)) { // new handle, we should add the key to journal ensure we can rebuild ByteBuffer bb = ByteBuffer.allocate(8 + 8 + 4 + masterKey.length); bb.putLong(ledgerId); bb.putLong(METAENTRY_ID_LEDGER_KEY); bb.putInt(masterKey.length); bb.put(masterKey); bb.flip(); if (null == masterKeyCache.putIfAbsent(ledgerId, masterKey)) { journal.logAddEntry(bb, new NopWriteCallback(), null); } } return l; }
public Observable waitForLastAddConfirmedUpdate( long ledgerId, long previoisLAC, Observer observer) throws IOException { LedgerDescriptor handle = handles.getReadOnlyHandle(ledgerId); return handle.waitForLastAddConfirmedUpdate(previoisLAC, observer); }
protected void addEntryByLedgerId(long ledgerId, ByteBuffer entry) throws IOException, BookieException { byte[] key = ledgerStorage.readMasterKey(ledgerId); LedgerDescriptor handle = handles.getHandle(ledgerId, key); handle.addEntry(entry); }