Completable Future inside completable future - java-8

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

Related

CompletableFuture in case of if statment

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)

Delayed dialog with resume handler

I have the following scenario I think I'm doing it wrong.
I have a RootDialog which calls a ResultDialog. The ResultDialog presents the user a list of results (using HeroCard).
The ResultDialog closes itself using context.Done(..) after the message was posted.
In the RootDialog- AfterResultDialog Resume handler I want to ask the user if he has found the matching result, using another dialog (NotificationDialog), but I want to do that after 30 seconds.
After some research, this seems like it must be done using proactive messages.
It this example, I found a way to post the NotificationDialog in a proactive way.
private async Task AfterResultDialog(IDialogContext context, IAwaitable<object> result)
{
var message = await result as IMessageActivity;
var conversationReference = context.Activity.ToConversationReference();
ConversationStarter.conversationReference = JsonConvert.SerializeObject(conversationReference);
t = new Timer(timerEvent);
t.Change(30000, Timeout.Infinite);
context.Wait<string>(NotificationDialogAfter);
}
public void timerEvent(object target)
{
t.Dispose();
ConversationStarter.Resume();
}
But the problem I have is that I'm interested in the result of this NotifcationDialog to know what the user wants to do next.
But all examples I found using proactive-messages do not regard the result of a proactive message with dialog:
public class ConversationStarter
{
public static string conversationReference;
public static async Task Resume()
{
var message = JsonConvert.DeserializeObject<ConversationReference>(conversationReference).GetPostToBotMessage();
var client = new ConnectorClient(new Uri(message.ServiceUrl));
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
var botData = scope.Resolve<IBotData>();
await botData.LoadAsync(CancellationToken.None);
var task = scope.Resolve<IDialogTask>();
// here it seems only to be possible to call a dialog using Void
var dialog = new NotificationDialog();
task.Call(dialog.Void<object, IMessageActivity>(), null);
await task.PollAsync(CancellationToken.None);
await botData.FlushAsync(CancellationToken.None);
}
}
}
The NotificationDialogAfter handler should decide based on the user input which dialog to call next:
private async Task NotificationDialogAfter(IDialogContext context, IAwaitable<string> result)
{
var whereToContinue = await result;
if (whereToContinue.Equals("Start over"))
{
context.ClearAllConversationDataKeys();
context.Call(new TagDialog(), this.TagDialogAfter);
}
else if (whereToContinue == "Tell friends")
{
context.Call(new TellFriendsDialog(), TellFriendsDialogAfter);
}
else if (whereToContinue == "Feedback")
{
context.Call(new FeedbackDialog(), this.FeedbackDialogAfter);
}
}
So what I basically want is that the result of the NotificationDialog is forwarded to the NotificationDialogAfter handler which the Root dialog is waiting for.
Is this even possible?
I solve the problem by defining static continue handlers (in GlobalContinueHandler), that I can provide inside the NotificationDialog, when calling other dialogs.
[Serializable]
public class NotificationDialog : IDialog<string>
{
public Task StartAsync(IDialogContext context)
{
PromptDialog.Choice(context, Resume, new List<string> { "yes", "no" },
"Found what you're looking for?");
return Task.CompletedTask;
}
private async Task Resume(IDialogContext context, IAwaitable<string> result)
{
var message = await result;
if (message == "yes")
{
context.Call(new SignupDialog(), GlobalContinueHandler.SignupDialogAfter);
}
else
{
context.Call(new FeedbackDialog(), GlobalContinueHandler.FeedbackDialogAfter);
}
}
}
I'm really not fan of this solution but for now it seems to work.

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.

how to implement async method using Task Parallel Library for I/O operations

I found that for expensive IO bound operation I can use TaskCompletionSource
as shown here http://msdn.microsoft.com/en-us/library/hh873177.aspx#workloads
But the example shown is only waiting for some time and return DateTime.
public static Task<DateTimeOffset> Delay(int millisecondsTimeout)
{
TaskCompletionSource<DateTimeOffset> tcs = null;
Timer timer = null;
timer = new Timer(delegate
{
timer.Dispose();
tcs.TrySetResult(DateTimeOffset.UtcNow);
}, null, Timeout.Infinite, Timeout.Infinite);
tcs = new TaskCompletionSource<DateTimeOffset>(timer);
timer.Change(millisecondsTimeout, Timeout.Infinite);
return tcs.Task;
}
Above code waits for timeout. I have a database call which I want to fire in the above way, but little confused in how to write it:
using (var context = new srdb_sr2_context())
{
return context.GetData("100", "a2acfid");
}
I wrote the function as below, but not sure if this is correct way of doing it:
TaskCompletionSource<IList<InstructorsOut>> tcs = null;
Timer timer = null;
timer = new Timer(delegate
{
timer.Dispose();
//prepare for expensive data call
using (var context = new srdb_sr2_context())
{
var output = context.GetData("100", "a2acfid");
//set the result
tcs.TrySetResult(output);
}
}, null, Timeout.Infinite, Timeout.Infinite);
tcs = new TaskCompletionSource<IList<InstructorsOut>>(timer);
timer.Change(0, Timeout.Infinite);
return tcs.Task;
Any help would be appreciated.
Your code doesn't make much sense to me. Timer is useful if you want to execute the code after some time, but that's not what you need here.
If you want to execute an operation on a background thread, you can use Task.Run():
Task<IList<InstructorsOut>> GetDataBackground()
{
return Task.Run(() =>
{
using (var context = new srdb_sr2_context())
{
return context.GetData("100", "a2acfid");
}
});
}
Using a background thread this way can be useful in UI apps, where you don't want to block the UI thread. But if you have something like ASP.NET application, this won't actually give you any performance or scalability improvements. For that, the GetData() method would have to be made truly asynchronous.

callback / delegate?

i have a doubt..
i would like to create a function and it will look like this...
public class A //this is just a class file
{
function dowork()
{
//work 1
INPUT = here in this line it should call a delegate function or raise event etc...
//work 2 using INPUT
}
}
public class B
{
function myfn()
{
A objA = new A();
objA.dowork();
}
}
In the "Class A" we will raise event or so & it will display a windows form to user and then user will input some value & we need to return that value to Class A -> dowork method.... then only we should continue "work 2"
this should also support multi threading... anyone have idea how we can implement this??
thanks :)
You can use ManulResetEvent for this purpose: You run your input form and when it done that form set the event so you can catch it from A.dowork method. While the input in action you run the infinite loop, check event state and process application event to make you app responsible in this time:
public class A //this is just a class file
{
private ManualResetEvent _event;
public void dowork()
{
//work 1
_event = new ManualResetEvent(false);
//INPUT = here in this ...
Worker worker = new Worker();
worker.DoInput(_event);
while(true)
{
if(_event.WaitOne())
break;
Application.DoEvents();
}
//work 2 using INPUT
}
}
class Worker
{
private ManualResetEvent _event;
public void DoInput(ManualResetEvent #event)
{
_event = #event;
// Show input form here.
// When it done, you call: _event.Set();
}
}
Also, I suggest you (if you can) use Async library (it is available as a standalone setup). There you can implement it in much more straightforward way:
public class A //this is just a class file
{
public async void dowork()
{
//work 1
//INPUT = here in this ...
Worker worker = new Worker();
wait worker.DoInput();
//work 2 using INPUT
}
}
class Worker
{
public async void DoInput()
{
InputForm form = new InputForm();
wait form.ShowInput();
}
}
public class B
{
async void myfn()
{
A objA = new A();
wait objA.dowork();
}
}
As you see you just wait while other piece of code get executed without any UI locking and events.
I can provide deeper explanation of how async/wait works here if you need.

Resources