# How do I orchestrate async tasks

**URL:** <https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848>\
**Category:** Ignition\
**Created:** [October 30, 2022, 2:40am UTC](https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848 "2022-10-30T02:40:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![scottmwyant](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/scottmwyant/32/66369_2.png) [@scottmwyant](https://forum.inductiveautomation.com/u/scottmwyant)\
**Post date:** [October 30, 2022, 2:40am UTC](https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848/1 "2022-10-30T02:40:23Z")

</div>

I don’t have a Java background so maybe what I’m asking is more of a Java question than an Ignition question.

How do I handle a collection of async calls? I have a bunch of API calls to make and I want to use `system.net.httpClient().getAsync` every x minutes. The individual calls are unrelated other than the desired frequency.

How do I orchestrate the calls? I’d like to know when everything has completed.

C# Task.WhenAll() is what I have in mind. Don’t know the equivalent concept in Ignition / Java.

Reference: [Task.WhenAll Method (System.Threading.Tasks) | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=net-6.0)

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [October 30, 2022, 10:39am UTC](https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848/2 "2022-10-30T10:39:14Z")

</div>

It's possible that this could be of use to you:

> [@Managing multiple asynchronous threads](https://forum.inductiveautomation.com/t/managing-multiple-asynchronous-threads/37185/2):
>
> To manage long-running jython threads through scripting restarts, you need to: Place the thread object in a dictionary that retains its content through script restarts. I used to recommend the dictionary from system.util.getGlobals(), but that is no longer suitable. I created a free [Life Cycle Module](http://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/14) that provides such dictionaries going forward. Write the asynchronous function’s loop so that it regularly checks [Thread.interrupted()](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupted--), particularly after any java I/O operations. Clean up …

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 30, 2022, 12:44pm UTC](https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848/3 "2022-10-30T12:44:29Z")

</div>

The key is that the `promise` is a thin wrapper around a Java [CompletableFuture](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CompletableFuture.html). Which implements the [CompletionStage](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CompletionStage.html) interface, that has numerous ways to combine results with further actions. The promise wrapper exposes the most import one: `.whenComplete()`, that takes a function of two arguments. This is the `BiConsumer<>` async interface. You should create a class implementing `BiConsumer` with the tracking/counting/accounting logic you wish, and attach it to each promise.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 31, 2022, 4:22pm UTC](https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848/4 "2022-10-31T16:22:48Z")

</div>

> [@scottmwyant](#):
>
> C# Task.WhenAll()

The most equivalent would probably be [`CompletableFuture.allOf`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CompletableFuture.html#allOf(java.util.concurrent.CompletableFuture...)), using the underlying `CompletableFuture` on the `Promise` as Phil already called out.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 31, 2022, 4:34pm UTC](https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848/5 "2022-10-31T16:34:20Z")

</div>

The downside to `.allOf()` is that you can't construct it incrementally. A well-designed consumer class could accept more promises while earlier ones are running and completing. Such a class can also **process the results** as it goes.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [October 31, 2022, 6:41pm UTC](https://forum.inductiveautomation.com/t/how-do-i-orchestrate-async-tasks/65848/6 "2022-10-31T18:41:50Z")

</div>

I recently needed to create some scripting to execute a task `x` times in parallel, but block the script from moving on until they completed.

Here is the script incase there's anything useful for you in it.

> <https://github.com/design-group/ignition-gateway-utilities/blob/master/projects/gateway-utilities/ignition/script-python/General/Multithreading/code.py>
