예제 #1
0
  /**
   * 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;
    }
  }
예제 #2
0
 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);
     }
   }
 }
예제 #3
0
 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);
     }
   }
 }
예제 #4
0
  /**
   * 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;
  }
예제 #5
0
 public Observable waitForLastAddConfirmedUpdate(
     long ledgerId, long previoisLAC, Observer observer) throws IOException {
   LedgerDescriptor handle = handles.getReadOnlyHandle(ledgerId);
   return handle.waitForLastAddConfirmedUpdate(previoisLAC, observer);
 }
예제 #6
0
 protected void addEntryByLedgerId(long ledgerId, ByteBuffer entry)
     throws IOException, BookieException {
   byte[] key = ledgerStorage.readMasterKey(ledgerId);
   LedgerDescriptor handle = handles.getHandle(ledgerId, key);
   handle.addEntry(entry);
 }