Yury Selivanov added the comment:
> Yury, what do you think of this yourself? Maybe you can explain it better
than Ilya?
TBH, I don't fully understand Ilya's case with threads, synchronous coroutines,
possible deadlocks etc. So I'll just explain what I would want out of this.
I don't like a few aspects of the current design of 'get_event_loop'. Mainly
because it creates an event loop implicitly, or it can just fail with a
RuntimeError under some conditions. When one has a few event loops, implicitly
called 'get_event_loop' from Future and other asyncio functions won't work
correctly. IMO, this is something that we at least should try to fix (even
though it's not an idiomatic use case for asyncio).
I now think that we don't need a new function for getting the currently running
event loop. Instead we can try to improve the `get_event_loop()` function a
little.
The core idea is to add a thread-local object `running_loop`, which will point
to the currently running event loop in the current thread. And `Loop._run`
method will set/reset a reference to the loop to `running_loop`.
`get_event_loop()` will then try to use the `running_loop` object first, and if
nothing is there, fall back to its current implementation.
Now, this is a point where everything becomes complicated. To quote
myself,--"Yes, the patch part is easy",--I don't think it is that easy anymore
;)
Currently, event loops are decoupled from policies. This means that we can't
make loops to use some hidden shared thread-local object (`running_loop`) that
policies and loops will work with. There has to be another new public policy
APIs that loops will use, for instance: 'set_running_event_loop()'. This won't
be the first case of event loop policy APIs being called from event loops --
another example is the `get_child_watcher` method.
With this new method, `Loop._run` will then look like this:
def _run(self):
policy = get_event_loop_policy()
policy.set_running_event_loop(self)
try:
... # current Loop._run implementation
finally:
policy.set_running_event_loop(None)
`policy.set_running_event_loop` call would raise a RuntimeError if it's called
if another event loop is currently running.
And the `get_event_loop()` function will look like this:
def get_event_loop():
policy = get_event_loop_policy()
loop = policy._get_running_event_loop()
if loop is not None:
return loop
# ... current get_event_loop implementation
So it all boils down to:
1. Adding a new policy API 'set_running_event_loop'.
2. Updating 'get_event_loop' to return the currently running event loop if it's
available, or else resorting to its current behaviour.
With this change it will be completely safe to use "get_event_loop" from
running coroutines or just about any code that runs in a context of an event
loop.
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue26969>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com