You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
async: review and refactor interaction between main thread and worker threads
Turns out that the async code was actually doing a lot of sync
stuff behind the scenes, which was causing very noticeable lag
and blocking behaviors when on bad connections.
The first change was to create main_thread_call helper. One marks
a "main thread only" method like so
~~~
main_thread_call def some_method
end
~~~
and method calls not in the main thread will cause an exception to
be raised. This is rather obviously meant for debugging.
From there, I've fixed calls that were coming from a worker thread
but should not have. In most cases, the pattern I had to change was
~~~
def some_method
@event_loop.defer ... do
do some async call in sync form (i.e. without blocks)
end
end
~~~
This was causing a lot of headaches as the code that turns async
calls into sync calls depends on a lot of synchronization (e.g.
with @delegator_obj), which was solved by having huge
@mutex.synchronize blocks, serializing major parts of the execution.
These calls have been changed into the non-blocking block form
(a.k.a. callback form), and are called from the main thread.
One major change is the removal of sub-genres of Async::NameService.
These were rather pointless, as turning a sync into an async object
can be done generically through to_async. The "new" Async::NameService
simply delegates to the non-async get in a worker thread and then
turns the non-async object into an async object.
Another major change is how Async::TaskContext creates itself. The
very unfortunate design choice in the async and proxy version of
TaskContext was to let them get a name as argument, and let them
do the resolution. This brings a lot of complexity in the async
case, as there is a zone where the async task context does not
have an underlying task context. Proxies are meant for that, not
async. Generally speaking, this interface should be changed to
do the name resolution in name_service (duh).
0 commit comments