jkosh44 commented on issue #978: Use CompleteableFuture compose to centralize 
commit logic
URL: https://github.com/apache/fluo/issues/978#issuecomment-351564607
 
 
   Just wanted to also copy some relevant comments from #722 by @jwonders, to 
avoid having to flip back and forth.
   
   >Assuming the creation of a data class, maybe called `AsyncCommitResult`, 
that can represent the various outcomes of the async commit, something like the 
following would be an alternative.
   >
   >In the end, the chaining might look similar to what @jkosh44 is suggesting 
except there would not be a need for the `CompletableFutureTask` or the 
`addCallback` method because the `thenComposeAsync` method already implements 
the desired behavior. There would be a bit less indirection as well.
   >
   > 
   >```
   >private CompletionStage<AsyncCommitResult> deleteLocks(CommitData cd, final 
long commitTs) {
   >    ArrayList<Mutation> mutations = new ArrayList<>(updates.size() + 1);
   >    // snip ---
   >    // start the finish commit task after the delete locks task completes 
successfully
   >    // in this case the finish commit task does not make a decision based 
on the result
   >    return env.getSharedResources().getBatchWriter()
   >            .writeMutationsAsyncCF(mutations)
   >            .thenComposeAsync(x -> finishCommit(cd, commitTs), executor());
   >}
   > 
   >private CompletionStage<AsyncCommitResult> finishCommit(CommitData cd, long 
commitTs) {
   >    ArrayList<Mutation> afterFlushMutations = new ArrayList<>(2);
   >    // snip ---
   >    return env.getSharedResources().getBatchWriter()
   >            .writeMutationsAsyncCF(afterFlushMutations)
   >            .thenApply(x -> AsyncCommitResult.committed());
   >}
   > ```
   >For the _fail-fast_ cases, it is reasonable to return a completion stage 
that is immediately failed, and for the synchronous tasks, it is reasonable to 
just perform them synchronously and then return an already-completed future.
   
   And 
   
   >The purpose of `AsyncCommitResult` is to capture the result of the async 
operation. Terminal steps would be able to create a concrete value of this 
result class because they are aware of successful completion or errors. 
Intermediate steps would return a future based on additional composed async 
steps.
   
   >In the code I had posted, the `finishCommit` method is a terminal step that 
returns the `committed()` status upon successful completion. The `deleteLocks` 
is an intermediate step that does its work then composes the result with the 
`finishCommit` step. Some steps might return immediately upon exceptional 
conditions and perform composition on normal conditions.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to