blob: 8e2e633a35a298b9bb3f82ec29b9a46cdeb4a8fe [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.bookkeeper.client.api;
import java.util.concurrent.CompletableFuture;
import org.apache.bookkeeper.common.annotation.InterfaceAudience.Public;
import org.apache.bookkeeper.common.annotation.InterfaceStability.Unstable;
import org.apache.bookkeeper.common.concurrent.FutureUtils;
/**
* Provide read access to a ledger.
*
* @since 4.6
*/
@Public
@Unstable
public interface ReadHandle extends Handle {
/**
* Read a sequence of entries asynchronously.
*
* @param firstEntry
* id of first entry of sequence
* @param lastEntry
* id of last entry of sequence, inclusive
* @return an handle to the result of the operation
*/
CompletableFuture<LedgerEntries> readAsync(long firstEntry, long lastEntry);
/**
* Read a sequence of entries asynchronously.
*
* @param startEntry
* start entry id
* @param maxCount
* the total entries count.
* @param maxSize
* the total entries size.
* @return an handle to the result of the operation
*/
default CompletableFuture<LedgerEntries> batchReadAsync(long startEntry, int maxCount, long maxSize) {
CompletableFuture<LedgerEntries> future = new CompletableFuture<>();
future.completeExceptionally(new UnsupportedOperationException());
return future;
}
/**
* Read a sequence of entries synchronously.
*
* @param firstEntry
* id of first entry of sequence
* @param lastEntry
* id of last entry of sequence, inclusive
* @return the result of the operation
*/
default LedgerEntries read(long firstEntry, long lastEntry) throws BKException, InterruptedException {
return FutureUtils.<LedgerEntries, BKException>result(readAsync(firstEntry, lastEntry),
BKException.HANDLER);
}
/**
*
* @param startEntry
* start entry id
* @param maxCount
* the total entries count.
* @param maxSize
* the total entries size.
* @return the result of the operation
*/
default LedgerEntries batchRead(long startEntry, int maxCount, long maxSize)
throws BKException, InterruptedException {
return FutureUtils.result(batchReadAsync(startEntry, maxCount, maxSize), BKException.HANDLER);
}
/**
* Read a sequence of entries asynchronously, allowing to read after the LastAddConfirmed range.
* <br>This is the same of
* {@link #read(long, long) }
* but it lets the client read without checking the local value of LastAddConfirmed, so that it is possible to
* read entries for which the writer has not received the acknowledge yet. <br>
* For entries which are within the range 0..LastAddConfirmed BookKeeper guarantees that the writer has successfully
* received the acknowledge.<br>
* For entries outside that range it is possible that the writer never received the acknowledge
* and so there is the risk that the reader is seeing entries before the writer and this could
* result in a consistency issue in some cases.<br>
* With this method you can even read entries before the LastAddConfirmed and entries after it with one call,
* the expected consistency will be as described above for each subrange of ids.
*
* @param firstEntry
* id of first entry of sequence
* @param lastEntry
* id of last entry of sequence, inclusive
* @return an handle to the result of the operation
*
* @see #readAsync(long, long)
* @see #readLastAddConfirmedAsync()
*/
CompletableFuture<LedgerEntries> readUnconfirmedAsync(long firstEntry, long lastEntry);
/**
* Read a sequence of entries synchronously.
*
* @param firstEntry
* id of first entry of sequence
* @param lastEntry
* id of last entry of sequence, inclusive
* @return an handle to the result of the operation
*
* @see #readUnconfirmedAsync(long, long)
*/
default LedgerEntries readUnconfirmed(long firstEntry, long lastEntry)
throws BKException, InterruptedException {
return FutureUtils.<LedgerEntries, BKException>result(readUnconfirmedAsync(firstEntry, lastEntry),
BKException.HANDLER);
}
/**
* Obtains asynchronously the last confirmed write from a quorum of bookies. This
* call obtains the last add confirmed each bookie has received for this ledger
* and returns the maximum. If the ledger has been closed, the value returned by this
* call may not correspond to the id of the last entry of the ledger, since it reads
* the hint of bookies. Consequently, in the case the ledger has been closed, it may
* return a different value than getLastAddConfirmed, which returns the local value
* of the ledger handle.
*
* @return an handle to the result of the operation
* @see #getLastAddConfirmed()
*/
CompletableFuture<Long> readLastAddConfirmedAsync();
/**
* Obtains asynchronously the last confirmed write from a quorum of bookies.
*
* @return the result of the operation
* @see #readLastAddConfirmedAsync()
*/
default long readLastAddConfirmed() throws BKException, InterruptedException {
return FutureUtils.<Long, BKException>result(readLastAddConfirmedAsync(),
BKException.HANDLER);
}
/**
* Obtains asynchronously the last confirmed write from a quorum of bookies
* but it doesn't wait all the responses from the quorum. It would callback
* immediately if it received a LAC which is larger than current LAC.
*
* @return an handle to the result of the operation
*/
CompletableFuture<Long> tryReadLastAddConfirmedAsync();
/**
* Obtains asynchronously the last confirmed write from a quorum of bookies
* but it doesn't wait all the responses from the quorum.
*
* @return the result of the operation
* @see #tryReadLastAddConfirmedAsync()
*/
default long tryReadLastAddConfirmed() throws BKException, InterruptedException {
return FutureUtils.<Long, BKException>result(tryReadLastAddConfirmedAsync(),
BKException.HANDLER);
}
/**
* Get the last confirmed entry id on this ledger. It reads the local state of the ledger handle,
* which is different from the {@link #readLastAddConfirmed()} call.
*
* <p>In the case the ledger is not closed and the client is a reader, it is necessary to
* call {@link #readLastAddConfirmed()} to obtain a fresh value of last add confirmed entry id.
*
* @see #readLastAddConfirmed()
*
* @return the local value for LastAddConfirmed or -1L if no entry has been confirmed.
*/
long getLastAddConfirmed();
/**
* Returns the length of the data written in this ledger so much, in bytes.
*
* @return the length of the data written in this ledger, in bytes.
*/
long getLength();
/**
* Returns whether the ledger is sealed or not.
*
* <p>A ledger is sealed when either the client explicitly closes it ({@link WriteHandle#close()} or
* {@link WriteAdvHandle#close()}) or another client explicitly open and recovery it
* {@link OpenBuilder#withRecovery(boolean)}.
*
* <p>This method only checks the metadata cached locally. The metadata can be not update-to-date because
* the metadata notification is delayed.
*
* @return true if the ledger is sealed, otherwise false.
*/
boolean isClosed();
/**
* Asynchronous read specific entry and the latest last add confirmed.
* If the next entryId is less than known last add confirmed, the call will read next entry directly.
* If the next entryId is ahead of known last add confirmed, the call will issue a long poll read
* to wait for the next entry <i>entryId</i>.
*
* @param entryId
* next entry id to read
* @param timeOutInMillis
* timeout period to wait for the entry id to be available (for long poll only)
* if timeout for get the entry, it will return null entry.
* @param parallel
* whether to issue the long poll reads in parallel
* @return an handle to the result of the operation
*/
CompletableFuture<LastConfirmedAndEntry> readLastAddConfirmedAndEntryAsync(long entryId,
long timeOutInMillis,
boolean parallel);
/**
* Asynchronous read specific entry and the latest last add confirmed.
*
* @param entryId
* next entry id to read
* @param timeOutInMillis
* timeout period to wait for the entry id to be available (for long poll only)
* if timeout for get the entry, it will return null entry.
* @param parallel
* whether to issue the long poll reads in parallel
* @return the result of the operation
* @see #readLastAddConfirmedAndEntry(long, long, boolean)
*/
default LastConfirmedAndEntry readLastAddConfirmedAndEntry(long entryId,
long timeOutInMillis,
boolean parallel)
throws BKException, InterruptedException {
return FutureUtils.<LastConfirmedAndEntry, BKException>result(
readLastAddConfirmedAndEntryAsync(entryId, timeOutInMillis, parallel),
BKException.HANDLER);
}
}