I need a Future Chain, where a process can finish while also returning a future as a handle for another process. I can't find a good way to explain it shorter, so I'll have to explain quite much: (not-quite-code)
Now M calls a1.do1().get().get(). I tested this in a minimum example and it seems to work, but I'd need a third level of Futures at a different point, and I might need to use only one level (so kinda a simple IFuture) at yet another. I'd really like to have an abstraction that can encapsulate all of these, so I could write that as return type for all functions do1..do4. The line >return new Future(d3Fut);< would then be replaced by something like IntermediateFuture.addIntermediateFuture() or similar.
I used IntermediateFuture here because it sounded like the solution that I seek, but it doesn't seem to have any .add(IFuture) or .add(IItnermediateFuture) functions.
Do you have an abstraction, that I can use, that solves this problem?
Thanks for your time
Hannes
Last edit: Hannes 2016-09-21
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Hannes,
I'm trying to understand why you need nested Futures.
in A2.do2(), you are returning a Future, that is already done and has another future as result.
As it does not contain other information, why would you need this future in between?
Hi Julian,
instead of Future.DONE I'm actually returning Values, in all ugly completeness I return IFuture<list\<ifuture\<map\<iexternalaccess, boolean="">>>>.</list\<ifuture\<map\<iexternalaccess,>
Now the issue is that if in do2() the line IFuture<Y> do3Fut = scheduleStep(this::do3);
would be replaced by IFuture<Y> do3Fut = do3();
then a definite deadlock would occur, since a1 is waiting for a2 to return from the do2() call and thus blocks the call do4() (from within do3()).
To circumvent that I use that step. The future from that step must not be called before a1.do1() returned to m, then only the step can process.
I hope this makes it a bit clearer.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
?
The concept of futures is that they can be returned immediately, even if the result is not there yet. Which is exactly what you described - or maybe I misunderstood you again :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I omitted the corresponding Interfaces, they are defined by their overriden methods.
I thought that any agent can not be run multiple times in parallel, and I assumed that would include blocking calls. That would mean that while a1 is in method do1() and blocks while waiting for a2.do2(), a1 would not be able to run do4(), thus it couldn't return to do2().
But it works, everything returns fine, but why?
Last edit: Hannes 2016-09-23
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Hannes,
the reason your code works is that calling a service is not the same as calling a java method on the component directly.
When you call a service, a new step is scheduled on the target component implicitely, so no blocking happens. As results can be passed at any time in the future because of the Future pattern, this works seamlessly.
You can read (much!) more about this at https://download.actoron.com/docs/nightlies/jadex-3.0.0-RC80/jadex-mkdocs/guides/ac/05%20Services/#concurrency.
The following image may help understanding this:
Last edit: Julian 2016-09-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Julian,
I do understand the Future system in principal, and I see now why my code above would work.
Sorry for taking your time and many thanks
Hannes
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Jadex Team,
I need a Future Chain, where a process can finish while also returning a future as a handle for another process. I can't find a good way to explain it shorter, so I'll have to explain quite much: (not-quite-code)
There are three Agents: M(anager), A1 & A2
Now M calls a1.do1().get().get(). I tested this in a minimum example and it seems to work, but I'd need a third level of Futures at a different point, and I might need to use only one level (so kinda a simple IFuture) at yet another. I'd really like to have an abstraction that can encapsulate all of these, so I could write that as return type for all functions do1..do4. The line >return new Future(d3Fut);< would then be replaced by something like IntermediateFuture.addIntermediateFuture() or similar.
I used IntermediateFuture here because it sounded like the solution that I seek, but it doesn't seem to have any .add(IFuture) or .add(IItnermediateFuture) functions.
Do you have an abstraction, that I can use, that solves this problem?
Thanks for your time
Hannes
Last edit: Hannes 2016-09-21
Hi Hannes,
I'm trying to understand why you need nested Futures.
in A2.do2(), you are returning a Future, that is already done and has another future as result.
As it does not contain other information, why would you need this future in between?
The
IntermediateFuturetype is meant for Futures that can return "intermediate" (not final) results to the receiver.You may check out the following chapter in our documentation (which has been restructured with the latest nightly builds):
https://download.actoron.com/docs/nightlies/jadex-3.0.0-RC79/jadex-mkdocs/futures/futures/#intermediate-futures
If you want to deliver multiple result values, you can also take a look at
Tuple2Future.I hope this helps, but i guess I didn't quite get your use case..
Regards,
Julian
Hi Julian,
instead of Future.DONE I'm actually returning Values, in all ugly completeness I return IFuture<list\<ifuture\<map\<iexternalaccess, boolean="">>>>.</list\<ifuture\<map\<iexternalaccess,>
Now the issue is that if in do2() the line
IFuture<Y> do3Fut = scheduleStep(this::do3);would be replaced by
IFuture<Y> do3Fut = do3();then a definite deadlock would occur, since a1 is waiting for a2 to return from the do2() call and thus blocks the call do4() (from within do3()).
To circumvent that I use that step. The future from that step must not be called before a1.do1() returned to m, then only the step can process.
I hope this makes it a bit clearer.
Would this work (import SResultListener from jadex.commons.future):
?
The concept of futures is that they can be returned immediately, even if the result is not there yet. Which is exactly what you described - or maybe I misunderstood you again :)
I just tried to build a minimum concept, and now I wonder whether I misunderstood something:
I omitted the corresponding Interfaces, they are defined by their overriden methods.
I thought that any agent can not be run multiple times in parallel, and I assumed that would include blocking calls. That would mean that while a1 is in method do1() and blocks while waiting for a2.do2(), a1 would not be able to run do4(), thus it couldn't return to do2().
But it works, everything returns fine, but why?
Last edit: Hannes 2016-09-23
Hi Hannes,

the reason your code works is that calling a service is not the same as calling a java method on the component directly.
When you call a service, a new step is scheduled on the target component implicitely, so no blocking happens. As results can be passed at any time in the future because of the Future pattern, this works seamlessly.
You can read (much!) more about this at https://download.actoron.com/docs/nightlies/jadex-3.0.0-RC80/jadex-mkdocs/guides/ac/05%20Services/#concurrency.
The following image may help understanding this:
Last edit: Julian 2016-09-26
Hi Julian,
I do understand the Future system in principal, and I see now why my code above would work.
Sorry for taking your time and many thanks
Hannes