Currently (in BookKeeper 4.5) we have several overloaded versions of the methods createLedger/createLedegerAdv/asyncCreateLeader/asyncCreateLeaderAdv. This methods are present because from version to version we added new configuration options for the Ledger.
In order to support new features in the future we need to have a more extensible API.
So we will introduce a new set of APIs to construct Ledgers, in the future this pattern will be extended to other operations, like deleteLedger/closeLedger/addEntry.
This is how the client code will look like:
BookKeeper bookeeper = ....;
CompletableFuture<LedgerHandler> future = bookkeeper.createLedger()
.withEnsembleSize(3)
.withWriteQuorumSize(2)
.withAckQuorumSize(1)
.withDigestType(DigestType.CRC32)
.withCustomMetadata(metadata)
.withPassword(password)
.withAdvancedOperations(true|false)
.apply();
LedgerHandler lh = future.get();
|
In order to achieve this goal we are going to introduce a ICreateBuilder interface
interface ICreateBuilder {
ICreateBuilder withEnsembleSize(...);
ICreateBuilder withWriteQuorumSize(...);
...
// old style callbacks
void execute(CreateCallback callback, Object ctx);
// support java8 completable future
CompletableFuture<IWriteHandler> apply();
// sync method
IWriteHandler create() throws BKException, InterruptedException;
} |
And we will make CrateLedgerOp implement such interface.
We are going to introduce an IBookKeeper interface
interface IBookKeeper {
ICreateBuilder createLedger();
IOpenBuilder openLedger();
} |
We are going to introduce a IWriteHandler interface which contains only the API related to writing to a Ledger.
In a similar way we are going to a IReadHandler which contains only the API related to reading to a Ledger and a IOpenBuilder
interface IOpenBuilder {
IOpenBuilder withRecovery(boolean)
IOpenBuilder withPassword(password)
IOpenBuilder withDigestType(digestType)
CompleableFuture<IReadHandler> apply(long ledgerId)
void open(long ledgerId, OpenCallback cb, Object ctx)
IReadHandler open(long ledgerId)
} |
No issue about migration and compatibility.
Legacy methods will be retained. No @Deprecated annotation will be added. Further removal of existing APIs will be evaluated in the future, maybe while starting a new major release, like 5.0.0
We can create similar API style for addEntry and other operations which need an extensible API.
It is to be discussed if we have to create two different interfaces for the simple LedgerHandler and the LedgerHandlerAdv, this will make things more comfortable for developers
An option will be like this
interface ICreateBuilder {
ICreateBuilderAdv withAdvancedOperations()
}
interface ICreateBuilderAdv {
CompletableFuture<AdvancedWritableLedgerHandler> execute();
} |
Maybe AdvancedLedgerHandler should not extend WritableLedgerHandler, because not all the operations on WritableLedgerHandler are available to 'adv' writers, but things will be tricky.
This is an example of an alternative API which has been rejected, as it will not be really extensible in the future
BookKeeper bookeeper = ....;
LedgerConfiguration ledgerConfiguration = LedgerConfiguration.builder()
.ensembleSize(3)
.writeQuorumSize(2)
.ackQuorumSize(1)
.digestType(DigestType.CRC32)
.customMetadata(Map<String, byte[]> metadata)
.password(password)
.advanced(true|false);
LedgerHandle ledger = bookeeper.createLedger(ledgerConfiguration);
|