Use uvloop as base event loop#93173
Conversation
|
Home Assistant had uvloop available in the past, and it was removed in 2019 (Home Assistant 0.104). Considering the part this touches, this definitely needs an architectural discussion first. Please make sure to create an architectural proposal and discussion in our architecture repository first. ../Frenck |
Yeah, I had a feeling something like this was required.... Done. |
Found one incompatibility at least right away (easy to fix) |
|
The following packages should need to be updated to support uvloop or uvloop updated to support
|
|
The performance improvements for sockets that read frequently (ie bluetooth, zeroconf, etc) is quite stunning so it would be nice if we could get this working but the |
Override sendto in HassEventLoop? It’s been many years since I’ve done C socket programming… Would multicast also be affected? |
|
@bdraco does changing a “” to “255.255.255.255” fix things? |
|
The string is actually |
| self._handle_cancellable_timer(timer, *args) | ||
| return timer | ||
|
|
||
| def create_future(self) -> asyncio.Future[Any]: |
There was a problem hiding this comment.
There are quite many places in the project where we call asyncio.Future directly instead of using loop.create_future which is recommended to cater for custom event loops. This may need to be solved in this PR, or a separate prerequisite PR, too.
There was a problem hiding this comment.
I thought set_event_loop_policy() takes care of that?
The only reason I overrode the method was to periodically prune the HassJob cancellable timers which I need to manually keep track of.
I figured that was the best place to do it since it won’t effect the event loop too much and HA creates lots of tasks.
There was a problem hiding this comment.
Why do you need to prune the timers?
Edit: you need to access loop._scheduled
There was a problem hiding this comment.
I don't see that there is a way to access loop._timers in uvloop.
It would be nicer if there was a public method to do that as it would avoid the complexity here. I don't know how willing they would be to add something like that
There was a problem hiding this comment.
If you could get something like that merged to uvloop you could avoid the subclassing
There was a problem hiding this comment.
Also I really don’t like that we need to access _scheduled in our current code base so if there is another option to refactor HA to avoid it that would also be a welcome change (if I had a suggestion to do that I think we already would have )
There was a problem hiding this comment.
There is a private attribute that acts similarly to _scheduled in the uvloop code. I just don’t know how to access it from Python.
There was a problem hiding this comment.
Why do you need to prune the timers?
Edit: you need to access
loop._scheduled
Yeah, if I knew how to do that, all of this method overriding would be unnecessary. I’m working around the fact I can’t access it by just keeping a list of cancellable timers.
I don’t know how to access an attribute coded in C in Python.
There was a problem hiding this comment.
Also I really don’t like that we need to access
_scheduledin our current code base so if there is another option to refactor HA to avoid it that would also be a welcome change (if I had a suggestion to do that I think we already would have )
Add it to the Hass object?
There was a problem hiding this comment.
If you could get something like that merged to uvloop you could avoid the subclassing
Well, I originally tried to access _timers directly, but I couldn't figure out how to as it is in C.
|
Ok, as far as I see it, the issues are:
Thoughts and/or suggestions and/or other issues? |
|
I cleaned up the HassEventLoop._scheduled to just use a WeakSet and not bother to prune. I'm at a loss as to what to do about broadcast, but I've logged an issue against uvloop. |
|
The branch is tainted with unrelated old commits. Please rebase and remove those or start over in a fresh branch and PR. |
|
So, I’ve logged an issue against uvloop and broadcast, but haven’t even gotten a comment on it. Also, I’ve noticed that uvloop drags in cython/gcc/etc instead of just downloading a wheel. I’m guessing we probably don’t want that either. Logged an issue, and still, silence. |
We build our own wheels so this likely isn't a problem unless wheels fail to build manually |
|
selector overhead is at the top of profiles all the time so I started working through that in a series of cpython PRs python/cpython#106555 Hopefully we will get uvloop one day, but in the mean time there are still some wins that can be made on the cpython side |
|
Because there hasn't been any activity on this PR for quite some time now, I've decided to close it for being stale. Feel free to re-open this PR when you are ready to pick up work on it again 👍 ../Frenck |
Breaking change
uvloop is a faster implementation of the standard asyncio loop, this change implements HA's main event loop using uvloop as opposed to the standard asyncio loop
Type of change
Additional information
See this link for benchmarks before and after uvloop implementation.
Checklist
black --fast homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all..coveragerc.To help with the load of incoming pull requests: