You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 13 Next »

Motivation

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.

Proposed Change

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<WriteHandler> future = bookkeeper.createLedger()
    .withEnsembleSize(3)
    .withWriteQuorumSize(2)
    .withAckQuorumSize(1)
    .withDigestType(DigestType.CRC32)                                       
    .withCustomMetadata(metadata)
    .withPassword(password)
    .apply();
WriterHandler lh = future.get();

 CompletableFuture<WriteHandlerAdv> future = bookkeeper.createLedger()
    .withEnsembleSize(3)
    .withWriteQuorumSize(2)
    .withAckQuorumSize(1)
    .withDigestType(DigestType.CRC32)                                       
    .withCustomMetadata(metadata)
    .withPassword(password)
    .withLedgerId(ledgerId)
    .makeAdv()
    .apply();
WriterHandlerAdv lh = future.get();
 

In order to achieve this goal we are going to introduce CreateBuilder and CreateBuilderAdv interfaces

interface CreateBuilder {
     CreateBuilder withEnsembleSize(...);
     CreateBuilder withWriteQuorumSize(...);
     ...
     CreateAdvBuilder makeAdv();

     // old style callbacks
     void execute(CreateCallback callback, Object ctx);
     // support java8 completable future
     CompletableFuture<WriteHandler> apply();
     // sync method
     WriteHandler create() throws BKException, InterruptedException;
 }
interface CreateBuilderAdv {
     // old style callbacks
     void execute(CreateCallback callback, Object ctx);
     // support java8 completable future
     CompletableFuture<WriteHandlerAdv> apply();
     // sync method
     WriteHandlerAdv create() throws BKException, InterruptedException;

}

And we will make CrateLedgerOp implement such interfaces.

We are going to introduce an BookKeeperClient interface

interface BookKeeperClient extends AutoCloseable { 
      CreateBuilder createLedger();
      OpenBuilder   openLedger();
}

We are going to introduce WriteHandler and WriteHandlerAdv interfaces which contains only the API related to writing to a Ledger, following the LedgerHandler/LedgerHandlerAdv semantics.

In a similar way we are going to introduce a ReadHandler which contains only the API related to reading to a Ledger and a OpenBuilder.

Please note that WriteHandler and WriteHandlerAdv will extend ReadHandler as writer need to be able to read its own writes.

A common LedgerHandler interface will be a base interface for ReadHandler and it will contain basic operations like 'close'

 interface OpenBuilder {
     OpenBuilder withRecovery(boolean)
     OpenBuilder withPassword(password) 
     OpenBuilder withDigestType(digestType)
     CompleableFuture<ReadHandler> apply(long ledgerId)
     void open(long ledgerId, OpenCallback cb, Object ctx)
     ReadHandler open(long ledgerId)
}

interface LedgerHandler extends AutoCloseable {
     void close();
     void asyncClose(CloseCallback cb, Object ctx);
}

interface ReadHandler extends ILedgerHandler {
     void readEntries();
     long readLastAddConfirmed();
     .....
     
}
interface IWriteHandler extends IReadHandler {
     void addEntry(byte[] data)
     void sync(...)
}
interface IWriteHandlerAdv extends IReadHandler {
     void addEntry(long entryID, byte[] data)
     void sync(...)
}

 

Migration Plan and Compatibility

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

Further works

We can create similar API style for addEntry, readEntries and other operations which need an extensible API.

We would leverage CompletableFuture for operations like close, delete, addEntry, readEntries....

Rejected Alternatives

This is an example of an alternative API which has been rejected, as it will not be really extensible in the future.

The rejected idea is about using the builder pattern for creating LedgerConfiguration structures and not directly ledgers

        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);

 

 

  • No labels