CompletableFuture in case of if statment - java-8

I have 2 CompletableFutures and 3 methods that have to occur each after the other.
However, in some cases the second method isn't necessary.
CompletableFuture<Boolean> cf1 = supplyASync.(() ->( doSomething1()));
CompletableFuture<Boolean> cf2 = new CompletableFuture<Boolean>();
if(someThing){
cf2 = cf1.thenApplyAsync(previousResult -> doSomething2());
}
else{
cf2 = cf1;
}
if (SomeThing2) {
cf2.thenApplyAsync(previousResult ->doSomeThing3());
}
Bassicly what I'm trying to do is that doSomething2 will run after doSomething1 (if needed), but anyway that doSomeThing3 will execute after the first or both of them.
Is it the right way to do it ? Or is there better way ?

The code is being executed in sequence, that is first completable future 1, then completable future 2 (if applies) and finally task 3.
By this reason, you can use a single CompletableFuture:
CompletableFuture<Boolean> cf = CompletableFuture.supplyAsync(() -> {
if (doSomething1()) {
doSomething2();
}
doSomething3();
// return something
});
And handling the boolean results would be something like:
CompletableFuture<Boolean> cf = CompletableFuture.supplyAsync(() -> {
boolean result;
if (result = doSomething1()) {
result = doSomething2();
}
return result && doSomething3();
});
// handle future as you need, e.g. cf.get() to wait the future to end (after task 3)

Related

RxJs channing, setting and reading external values

I'm new in rxjs world and I have to rewrite some code. So, I draft my ideas.
I have a request, which could fail and return an observable. I simulate that with the ob-variable and two map operations. Then, I try to catch an error. I need the result in my local variable selected and raise an event on isChanged. I call my function now via subscription. I don't need a result.
My question: Is one big pipe enough and can I use following approach for the work with my local variables?
import { of, map, Observable, tap, Subject, throwError, EMPTY } from 'rxjs';
import { catchError } from 'rxjs/operators';
let selected = 0;
const isChanged = new Subject<number>();
function myfunc(): Observable<boolean> {
const ob = of(1,3,4,5,7);
return ob.pipe(
// simulates a http request
map(v => v*2),
// simulates a rare error condition
map(v => {
// if (v === 8) { throw `four`; }
if (v === 10) { throw `ten`; }
return v;
}),
// play with different failure situations
catchError((e) => {
if (e === `four`) {
return of(4);
}
if (e === `ten`) {
return EMPTY;
}
console.warn(e);
return throwError(e);
}
),
// I need the result in a local variable
// I need a information about success
// I need the result not really
map((res) => {
selected = res;
isChanged.next(res);
return true;
})
);
}
console.log(`a: selected is ${selected}`);
isChanged.subscribe(v =>
console.log(`b: isChanged received: ${v}, selected is ${selected}`));
console.log(`c: selected is ${selected}`);
// I have to call the function
myfunc().subscribe((b) => {
console.log(`d: selected is ${selected}`);
});
I create the world in Stackblitz too:
https://stackblitz.com/edit/rxjs-6fgggh?devtoolsheight=66&file=index.ts
I see results like expected. But I'm not sure if all ideas are the right way to solve all problems.
Thanks for you thought.

Completable Future inside completable future

I have couple of completable future in my code. Inside one of completable future I want another completable future (completable future inside completable future) e.g.
public CompletableFuture<List<Employee>> buildEmployee (List<EmployeeResponse> employeeInfo) {
return supplyAsync(() -> {
Map<String, List<EmployeeReward>> rewards = rewards(employeeInfo);
Map<String, List<EmployeePoints>> points = points(employeeInfo);
}, executor);
}
In above method rewards and points are two independent sequential call, I want it to parallel call for them for that I tried -
public CompletableFuture<List<Employee>> buildEmployee (List<EmployeeResponse> employeeInfo) {
return supplyAsync(() -> {
CompletableFuture<Map<String, List<EmployeeReward>>> rewards = reward(employeeInfo);
CompletableFuture<Map<String, List<EmployeePoints>>> points = points(employeeInfo);
CompletableFuture<Void> futures = allOf(rewards, points);
}, executor);
}
Is is correct way to do this? How can I improve it if not correct way?
I am building <List<Employee>> as below
employeeInfo.stream.map(employee -> Employee.builder().
.<someEmplyInfo>
.points(points.getOrDefault(employee.getEmpId, newArrayList()))
);
It is important to handle any exceptions in exceptionally block for individual futures.
Ideally, the flow of control should not be dependent on the exception handling logic, it should be wrapped in a status object that can be used to evaluate if further processing should happen.
Adding a thenApply post the allOf method and then fetching the results within the thenApply block should do the trick
public CompletableFuture<List<Employee>> buildEmployee(List<EmployeeResponse> employeeInfo) {
//Build the future instance for reward
CompletableFuture<Map<String, List<EmployeeReward>>> rewardsFuture = reward(employeeInfo)
.exceptionally(throwable -> {
//Handle the error
return null;
});
//Build the future instance for points
CompletableFuture<Map<String, List<EmployeePoints>>> pointsFuture = points(employeeInfo)
.exceptionally(throwable -> {
//Handle the error for rewards
return null;
});
return CompletableFuture.allOf(rewardsFuture, pointsFuture).thenApply(v -> {
try {
Map<String, List<EmployeeReward>> rewardsResult = rewardsFuture.get();
Map<String, List<EmployeePoints>> pointsResult = pointsFuture.get();
//Convert the above map to the desired list of string
List<Employee> buildEmployeeResult = null;
return buildEmployeeResult;
}
catch (Exception e) {
//Handle exception
return null;
}
}, executor);
}
private CompletableFuture<Map<String, List<EmployeePoints>>> points(List<EmployeeResponse> employeeInfo) {
return supplyAsync(() -> {
//Logic for points synchronous
});
}
private CompletableFuture<Map<String, List<EmployeeReward>>> reward(List<EmployeeResponse> employeeInfo) {
return supplyAsync(() -> {
//Logic for rewards synchronous
});
}
In the above approach you are using Async thread to execute buildEmployee method, which means Async thread is responsible to make two API calls rewards and points and then it will combine the result. so in the above approach this method is executing asynchronously but not the API calls.
But you can do it another way by making API calls Asynchronously, do the reward call asynchronously by using supplyAsync and then do the points call using Main thread. Finally block the main thread until async call get finished and then combine the result
public CompletableFuture<List<Employee>> buildEmployee (List<EmployeeResponse> employeeInfo) {
// First call is Async call
CompletableFuture<Map<String, List<EmployeeReward>>> rewards = CompletableFuture.supplyAsync(()->reward(employeeInfo), executor);
//Second call by main thread
Map<String, List<EmployeePoints>>> points = points(employeeInfo);
// main thread is Blocked and get the result of the future.
rewards.get(); //throws InterruptedException,ExecutionException
// Now combine the result and return list
return CompletableFuture.completedFuture(result);
}

Chaining several CompletionStage only if a condition is achieved

I have several CompletionStage methods that I'd like to chain. The problem is that the result of the first one will determine if the next ones should be executed. Right now the only way to achieve this seems to be passing "special" arguments to next CompletionStage so it doesn't execute the full code. For example:
public enum SomeResult {
RESULT_1,
RESULT_2,
RESULT_3
}
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
return CompletableFuture.supplyAsync(() -> {
// loooooong operation
if (someCondition)
return validValue;
else
return null;
}).thenCompose(result -> {
if (result != null)
return someMethodThatReturnsACompletionStage(result);
else
return CompletableFuture.completedFuture(null);
}).thenApply(result -> {
if (result == null)
return ChainingResult.RESULT_1;
else if (result.someCondition())
return ChainingResult.RESULT_2;
else
return ChainingResult.RESULT_3;
});
}
Since the whole code depends on the first someCondition (if it's false then the result will be RESULT_1, if not then the whole code should be executed) this construction looks a bit ugly to me. Is there any way to decide if 2nd (thenCompose(...)) and 3rd (thenApply(...)) methods should be executed?
You can do it like this:
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
CompletableFuture<SomeResult> shortCut = new CompletableFuture<>();
CompletableFuture<ResultOfFirstOp> withChain = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
// loooooong operation
if (someCondition)
withChain.complete(validValue);
else
shortCut.complete(SomeResult.RESULT_1);
});
return withChain
.thenCompose(result -> someMethodThatReturnsACompletionStage(result))
.thenApply(result ->
result.someCondition()? SomeResult.RESULT_2: SomeResult.RESULT_3)
.applyToEither(shortCut, Function.identity());
}
Instead of one CompletableFuture we create two, representing the different execution paths we might take. The loooooong operation is submitted as runnable then and will deliberately complete one of these CompletableFuture. The followup stages are chained to the stage representing the fulfilled condition, then both execution paths join at the last applyToEither(shortCut, Function.identity()) step.
The shortCut future has already the type of the final result and will be completed with the RESULT_1, the result of your nullpassing path, which will cause the immediate completion of the entire operation. If you don’t like the dependency between the first stage and the actual result value of the short-cut, you can retract it like this:
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
CompletableFuture<Object> shortCut = new CompletableFuture<>();
CompletableFuture<ResultOfFirstOp> withChain = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
// loooooong operation
if (someCondition)
withChain.complete(validValue);
else
shortCut.complete(null);
});
return withChain
.thenCompose(result -> someMethodThatReturnsACompletionStage(result))
.thenApply(result ->
result.someCondition()? SomeResult.RESULT_2: SomeResult.RESULT_3)
.applyToEither(shortCut.thenApply(x -> SomeResult.RESULT_1), Function.identity());
}
If your third step wasn’t exemplary but looks exactly like shown in the question, you could merge it with the code path joining step:
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
CompletableFuture<ResultOfSecondOp> shortCut = new CompletableFuture<>();
CompletableFuture<ResultOfFirstOp> withChain = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
// loooooong operation
if (someCondition)
withChain.complete(validValue);
else
shortCut.complete(null);
});
return withChain
.thenCompose(result -> someMethodThatReturnsACompletionStage(result))
.applyToEither(shortCut, result -> result==null? SomeResult.RESULT_1:
result.someCondition()? SomeResult.RESULT_2: SomeResult.RESULT_3);
}
then we only skip the second step, the someMethodThatReturnsACompletionStage invocation, but that can still stand for a long chain of intermediate steps, all skipped without the need to roll out a manual skipping via nullcheck.
For the sake of completeness I'm adding a new answer
Although the solution proposed by #Holger works great it's kinda strange to me. The solution I've been using involves separating different flows in different method calls and chaining them with thenCompose:
public enum SomeResult {
RESULT_1,
RESULT_2,
RESULT_3
}
public CompletionStage<SomeResult> someMethod(SomeArgument someArgument) {
return CompletableFuture.supplyAsync(() -> {
// loooooong operation
if (someCondition)
return operateWithValidValue(value);
else
return CompletableFuture.completedValue(ChainingResult.RESULT_1);
})
.thenCompose(future -> future);
public CompletionStage<SomeResult> operateWithValidValue(... value) {
// more loooong operations...
if (someCondition)
return CompletableFuture.completedValue(SomeResult.RESULT_2);
else
return doFinalOperation(someOtherValue);
}
public CompletionStage<SomeResult> doFinalOperation(... value) {
// more loooong operations...
if (someCondition)
return CompletableFuture.completedValue(SomeResult.RESULT_2);
else
return CompletableFuture.completedValue(SomeResult.RESULT_3);
}
NOTE: I've changed the algorithm from the question in sake of a more complete answer
All long operations could be potentially wrapped inside another CompletableFuture.supplyAsync with little effort
If you have to check only for null values you can solve using Optional. For example you should do:
public Bar execute(String id) {
return this.getFooById(id)
.thenCompose(this::checkFooPresent)
.thenCompose(this::doSomethingElse)
.thenCompose(this::doSomethingElseMore)
.thenApply(rankRes -> new Bar(foo));
}
private Optional<Foo> getFooById(String id) {
// some better logic to retrieve foo
return Optional.ofNullable(foo);
}
private CompletableFuture<Foo> checkFooPresent(Optional<Foo> optRanking) {
CompletableFuture<Foo> future = new CompletableFuture();
optRanking.map(future::complete).orElseGet(() -> future.completeExceptionally(new Exception("Foo not present")));
return future;
}
The checkFooPresent() receives an Optional, and if its value is null it complete exceptionally the CompletableFuture.
Obviously you need to manage that exception, but if you have previously setted an ExceptionHandler or something similar it should come for free.

Update instance in the first method before continue to run the second method in the same command

I have a method like this
public void LoadProgrammeListFromChannel(TVDailyScheduleParam scheduleParam, Action callback)
{
string url = Helper.GetProgrammeUrl(scheduleParam.Day, scheduleParam.Channel.Id); //1//
WebClient client = new WebClient(); //2//
client.OpenReadCompleted += new OpenReadCompletedEventHandler((sender, e) => //3//
{//5//
if (e.Error != null)
return;
try
{
_programmeList.Clear();
_programmeList = DataService.GetProgrammeList(e.Result);
// call method in MainVM to update View
callback();
}
finally
{
// close file stream
e.Result.Close();
}
});
client.OpenReadAsync(new Uri(url, UriKind.Absolute)); //4//
}
and I have a cammand like this
LoadWhatsonProgrammeCommand = new RelayCommand(()=>
{
foreach (TVDailyScheduleParam param in _tvDailyScheduleVM.ChannelList.Select(c => new TVDailyScheduleParam(DateTime.Today, c, false)))
{
TVDailyScheduleParam param2 = param;
_tvDailyScheduleVM.LoadProgrammeListFromChannel(param2, ()=>
{
RaisePropertyChanged(TV_DAILY_SCHEDULE_VM);
});
_tvDailyScheduleVM.GetWhatsonProgramme(param2, ()=>
{
RaisePropertyChanged(TV_DAILY_SCHEDULE_VM);
});
}
});
Now when I invoke the command. At first it runs _tvDailyScheduleVM.LoadProgrammeListFromChannel and invoke the LoadProgrammeListFromChannel method.
In the LoadProgrammeListFromChannel method it runs from 1 -> 2 -> 3. At 3, it's not completed sothat it runs to 4 and then back to the command and continue to run _tvDailyScheduleVM.GetWhatsonProgramme.
But the _programmeList in LoadProgrammeListFromChannel is not updated so that GetWhatsonProgramme does not run exactly.
How can I go back to LoadProgrammeListFromChannel in order to run 3 to update _programmeList before running _tvDailyScheduleVM.GetWhatsonProgramme ?
The behaviour you describe is "by design". Your method LoadProgrammeListFromChannel makes an asynchroneous call. This means within your method the sequence is 1 -> 2 -> 3 -> 4 -> return -> execute code in calling function -> then sometime later 5 and then the callback.
As a result LoadProgrammeListFromChannel and GetWhatsonProgramme are executed in parallel. So if GetWhatsonProgramme needs always to run after LoadProgrammeListFromChannel you will have the call to move GetWhatsonProgramme into your callback method, i.e.
LoadWhatsonProgrammeCommand = new RelayCommand(()=> {
var channelList = _tvDailyScheduleVM
.ChannelList
.Select(c => new TVDailyScheduleParam(
DateTime.Today,
c,
false
));
foreach (TVDailyScheduleParam param in channelList) {
TVDailyScheduleParam param2 = param;
_tvDailyScheduleVM.LoadProgrammeListFromChannel(param2, ()=> {
RaisePropertyChanged(TV_DAILY_SCHEDULE_VM);
_tvDailyScheduleVM.GetWhatsonProgramme(param2, ()=> {
RaisePropertyChanged(TV_DAILY_SCHEDULE_VM);
});
});
}
});
Alternatively, you could subscribe to the PropertyChangedEvent of your ViewModel and if the TV_DAILY_SCHEDULE_VM property has been changed, call the GetWhatsonProgramme from there, although this might not be desireable.

Replacing nested if statements

This is related to a chapter from beautiful code.
And in that chapter I read about the nested ifs.
The author was talking about deeply nested ifs as originator of bugs and less readable.
And he was talking about replacing nested ifs with case statements and decision tables.
Can anybody illustrate how to remove nested ifs with case (select case) and decision tables ?
Well, not directly an answer to your question since you specifically ask about switch/case statements, but here is a similar question.
Invert “if” statement to reduce nesting
This talks about replacing nested if's with guard-statements, that return early, instead of progressively checking more and more things before settling on a return value.
One example I always try to do is replace heavily nested if's like this (actually this one's not too bad but I've seen them up to 8 or 9 levels deep in the wild):
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
with this:
switch (i) {
case 1:
// action 1
break;
case 2:
// action 2
break;
case 3:
// action 3
break;
default:
// action 4
break;
}
I also try to keep the actions as small as possible (function calls are best for this) to keep the switch statement compressed (so you don't have to go four pages ahead to see the end of it).
Decision tables, I believe, are simply setting flags indicating what actions have to be taken later on. The "later on" section is simple sequencing of actions based on those flags. I could be wrong (it won't be the first or last time :-).
An example would be (the flag-setting phase can be complicated if's since its actions are very simple):
switch (i) {
case 1:
outmsg = "no paper";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
case 2:
outmsg = "no ink";
genmsg = true;
mailmsg = true;
phonemsg = false;
break;
default:
outmsg = "unknown problem";
genmsg = true;
mailmsg = true;
phonemsg = true;
break;
}
if (genmsg)
// Send message to screen.
if (mailmsg)
// Send message to operators email address.
if (phonemsg)
// Hassle operators mobile phone.
How about chained ifs?
Replace
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
with
if (condition1) {
do1;
} else if (condition2) {
do2;
} else if (condition3) {
do3;
}
This is much like switch statement for complex conditions.
Make the condition into booleans and then write boolean expression for each case.
If the code was:
if (condition1)
{
do1
}
else
{
if (condition2)
{
do2
}
else (condition3)
{
do3;
}
}
One can write it as:
bool cond1=condition1;
bool cond2=condition2;
bool cond3=condition3;
if (cond1) {do1;}
if (!cond1 and cond2) {do2;}
if (!cond1 and cond3) {do2;}
For decision tables, please see my answer to this question, or better still read chapter 18 in Code Complete 2.
You can just break once a part of the validation failed for example.
function validate(){
if(b=="" || b==null){
alert("Please enter your city");
return false;
}
if(a=="" || a==null){
alert("Please enter your address");
return false;
}
return true;
}
Decision tables are where you store the conditional logic in a data structure rather than within the code itself.
So instead of this (using #Pax's example):
if (i == 1) {
// action 1
} else {
if (i == 2) {
// action 2
} else {
if (i == 3) {
// action 3
} else {
// action 4
}
}
}
you do something like this:
void action1()
{
// action 1
}
void action2()
{
// action 2
}
void action3()
{
// action 3
}
void action4()
{
// action 4
}
#define NUM_ACTIONS 4
// Create array of function pointers for each allowed value of i
void (*actions[NUM_ACTIONS])() = { NULL, action1, action2, action3 }
// And now in the body of a function somewhere...
if ((i < NUM_ACTIONS) && actions[i])
actions[i]();
else
action4();
If the possibilities for i are not low-numbered integers then you could create a lookup table instead of directly accessing the ith element of the actions array.
This technique becomes much more useful than nested ifs or switch statements when you have a decision over dozens of possible values.
If and switch statements are not purely OO. They are conditional procedural logic, but do a very good job! If you want to remove these statements for a more OO approach, combine the 'State' and 'Descriptor' patterns.
You might also consider using the Visitor pattern.
Nested if are equivalent to the logical operator AND
if (condition1)
{
if (function(2))
{
if (condition3)
{
// do something
}
}
}
Equivalent code:
if (condition1 && function(2) && condition3)
{
// do something
}
In both cases, when an expression evaluates false, the subsequent expression will not be evaluated. For example, if condition1 is false, the function() will not be called, and condition3 won't be evaluated.
Another example some languages allow is this
switch true{
case i==0
//action
break
case j==2
//action
break
case i>j
//action
break
}

Resources