Is there a list of actions that for sure cannot be run in parallel? I just did some test and the first 2 actions I tried (“write to system log” and “send event”) turned out not being able to run in parallel
Additional question: does Home Assistant ever use threads for parallel execution, or only uses context-switching?
and then listen to that event in developer tools, I see that result is the same (sequences run one-by-one, not in parallel). However, when I add a delay after each write to log/send event:
Still not truly parallel but execution switches context. Also, I tried running each single sequence by 4 automations, that triggered at the same time. The results were the same as with single script+parallel.
I increased repeat count to 1k and I made each sequence wait for a boolean switch. I also added timestamps to the variables v1/v2/v3/v4 (to see when they were created).
You’re just comparing something that is added to the event loop vs something that just fires directly to the event bus. Events fire directly from the event bus, they don’t need to be added to a queue, where as service calls are added to the queue.
No, I compare an action to create event with an action to write to system log. I found that for both actions, concurrent execution doesn’t work but context switching is possible by injecting wait/delay/etc.
I wonder if this is a general rule in Home Assistant? I don’t say it’s wrong, actually it’s probably necessary. I’m trying to understand what actions are “safe” and what should I avoid in certain situations (e.g. trigger-based templates, where - as I now believe - you should avoid waiting/delaying, as it might cause them to miss an event).
I’m telling you what you’re comparing from a code perspective.
Events in ha (The event action) use hass.bus.fire which directly calls call_soon_threadsafe
where service call actions are called using asyncio.run_coroutine_threadsafe
here’s an explanation
If this is over your head, then all you need to know is:
Services will always behave like your test with system_log.write
Nothing in HA is parallel btw, it’s an event loop so something is always fired first from the main loop. Child threads are created & destroyed when the main loop needs (or doesn’t need) help.
What you’re seeing in your test is the functions getting added to the event loop in an order they will fire in.
EDIT: They both call from the event loop, sorry. I should be more explicit with my response.
The rule in HA is: First in first out of the event loop. It’s entirely based on how long it takes to get the coroutine or function into the event loop. It will likely be completely random and based on how fast your system is.
Thanks, I started to come to this conclusion too. The name “parallel” confused me and initially I expected it to work like e.g. in C#. Also what I wrote about trigger-based templates seems true. E.g. if you have an “action section” within trigger-based template:
and you quickly send an event to trigger that template, you’ll see lots of warnings in log (“trigger already running”). But if you remove the delay, then it’s fine. I believe it’s because there can only be 1 instance of given trigger template running, and “delay” moves the completion of current routine further in the queue.