# How to "watch" for a condition asynchronously inside a function

**URL:** <https://discourse.julialang.org/t/how-to-watch-for-a-condition-asynchronously-inside-a-function/19934>\
**Category:** General Usage\
**Created:** [January 22, 2019, 3:13pm UTC](https://discourse.julialang.org/t/how-to-watch-for-a-condition-asynchronously-inside-a-function/19934 "2019-01-22T15:13:03Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [January 22, 2019, 3:13pm UTC](https://discourse.julialang.org/t/how-to-watch-for-a-condition-asynchronously-inside-a-function/19934/1 "2019-01-22T15:13:03Z")

</div>

I am working on an epidemiological agent-based model. Suppose I have an array of Agents

```julia
mutable struct Human
    isinfected
end
agents = [Human(i) for i = 1:10000]

```

When the simulation starts, I introduce a random infected person into the population, i.e. `setup_random_infected()`, after which the main discrete-time simulation starts:

```julia
 ## main simulation loop.
    for t=1:SIM_TIME       
        contact_dynamics()
        infection_dynamics()
        data_collection()
    end

```

**Problem** : Sometimes the initial infected person recovers without making anyone else sick, due to stochascity or contact patterns. When this happens, I would like to kill the simulation (i.e. return from the function) without running through the entire for loop.

I can have an `if` statement, but i fear that this is too costly. Sure, when the initial person does recover and the basic reproduction number R0 is 0, this kills the loop. However, in the simulations where the epidemic takes off, I fear that constantly evaluating `if` statement is costly. This is because the `array` of humans (a “human” is a large `mutable struct`) is heap-allocated, and checking this person’s property, `human.isinfected` constantly is not going to be optimized.

```julia
## main simulation loop.
    for t=1:SIM_TIME       
        if initial_person == recover && R0 == 0
            return
        contact_dynamics()
        infection_dynamics()
        data_collection()
    end

```

I was wondering if there is a way to have the for loop run without an if statement, but still watch for that infected person and kill the loop if the epidemic dies.

_My Idea_\*: I was thinking something alone the lines of using channels plus `sync/async`.

```julia
@sync begin
   @async start_condition_check()
   @async start_main_time_loop()
end

```

Real problem: Although what I’ve described above is barebones, my real problem is that I am trying to calculate R0 on the fly. Out of, say 2000 Monte Carlo simulations, I want to keep only those simulations running that the R0 is some threshold for the initial infected. If R0 dosn’t reach the threshold, I would like to kill the simulation.  
Ideas and tips would be appreciated.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 22, 2019, 4:58pm UTC](https://discourse.julialang.org/t/how-to-watch-for-a-condition-asynchronously-inside-a-function/19934/2 "2019-01-22T16:58:45Z")

</div>

> [@affans](#):
>
> can have an `if` statement, but i fear that this is too costly. Sure, when the initial person does recover and the basic reproduction number R0 is 0, this kills the loop. However, in the simulations where the epidemic takes off, I fear that constantly evaluating `if` statement is costly.

Did you profile this? How much time is spent doing the check vs without it.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [January 22, 2019, 10:19pm UTC](https://discourse.julialang.org/t/how-to-watch-for-a-condition-asynchronously-inside-a-function/19934/3 "2019-01-22T22:19:59Z")

</div>

> [@affans](#):
>
> I can have an `if` statement, but i fear that this is too costly. Sure, when the initial person does recover and the basic reproduction number R0 is 0, this kills the loop. However, in the simulations where the epidemic takes off, I fear that constantly evaluating `if` statement is costly. This is because the `array` of humans (a “human” is a large `mutable struct` ) is heap-allocated, and checking this person’s property, `human.isinfected` constantly is not going to be optimized.

I’m not sure I follow the logic. It’s a single memory access, no? What about your other methods, `data_collection()` etc, don’t they also incur memory accesses? How long time, in nanoseconds, does a loop iteration take on average? It seems unlikely to me that checking a flag in each iteration would make any difference, but if it does a simple solution would be to not check it every single iteration, but say every 100 iterations.

I would very strongly recommend against any async solution killing the loop from another thread. That sounds like a very complicated, error-prone, debug-unfriendly solution, and I doubt that it’d be any more efficient.

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [January 22, 2019, 10:33pm UTC](https://discourse.julialang.org/t/how-to-watch-for-a-condition-asynchronously-inside-a-function/19934/4 "2019-01-22T22:33:35Z")

</div>

> [@bennedich](#):
>
> It seems unlikely to me that checking a flag in each iteration would make any difference, but if it does a simple solution would be to not check it every single iteration, but say every 100 iterations.

How do you check every 100’th iteration? Wouldn’t you then have to check for the loop `variable` now? I suppose checking the loop variable is faster.

I will profile the code. I hanv’t done that since its complicated and was not written in a modular way. It might not be as costly as I think, or atleast relative to the other functions run inside the loop.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [January 22, 2019, 10:53pm UTC](https://discourse.julialang.org/t/how-to-watch-for-a-condition-asynchronously-inside-a-function/19934/5 "2019-01-22T22:53:23Z")

</div>

> [@affans](#):
>
> How do you check every 100’th iteration? Wouldn’t you then have to check for the loop `variable` now? I suppose checking the loop variable is faster.

Yes, check the loop variable, or keep a separate variable, or double loops. I’d estimate that it adds about a nanosecond, unless you use division. I think you’re overthinking this issue.
