Comments (4)
Hi,
Thanks for the detailed explanation! I understand the issue, but can't see why it needs to be fixed: if you use a lock in a coroutine, it's probably because you need to synchronize IO operations. They will be invoked with await/yield from and most likely yield to the scheduler.
In other words: in which "real-world" case do you think that an asyncio.Lock will be used without yielding?
Rather than yield from asyncio.sleep(0)
, you can use loop.call_soon(lock.release)
to ensure that the lock will be released during the next loop iteration, which effectively makes yield from lock.acquire()
to yield to the scheduler.
from asyncio.
Thanks for taking the time to fully understand the issue. Typically application software fixes give significant weight to real-life use cases, whereas systems software such as libraries consider even remote cases. That's because there is a HUGE diversity of python users and if there is an issue, somebody or the other will encounter it. In other words, libraries such has this have to be a bit aspirational and strive to perfection.
That said, I dug deeper into this issue and found 2 things that make it moot.
-
Numerous other asyncio coroutines do not block in the fast path, including those used for mutual exclusions. Two random examples:
Event.wait()
andQueue.get()
.
Thus, firstly, fixing justLock
is of little consequence -- users must still be cautious about many other coroutines.
Secondly, I am not sure whether it is wise for all co-routines or even just mutual exclusion ones to be "fixed" so that they always yield to the scheduler, even in the fast path. In fact, I lean towards preserving the current fast paths.
Thirdly, I am inclined to believe that there should always be a way to tell whether the coroutine will yield to scheduler or not. -
There is indeed a method
Lock.locked()
that can predict whetherLock.acquire()
will yield to scheduler or not, andLock.locked()
itself does not yield to the scheduler.
This method can be used by minority users who may care about this condition. Hopefully other similar coroutines with a fast path also have similar predictor methods. -
This distantly relates to an earlier debate in #284 (not involving me) regarding the behavior of
asyncio.sleep(0)
. The call tosleep(t)
was actually de-optimized (in the context of this issue) to yield to scheduler even though it could just return without yielding whent == 0
. This was done to avoid adding a new method to the library.
Given the above discussion, it seems like a bad idea to have done so. I hope in light of the discussion in this issue, somebody decides to go with the original thought to addasync.nop
rather than overloadsleep
in an unusual way. -
Finally, I just noticed that the atypical behavior of
asyncio.sleep
is not even documented in the docstring. Hopefully the library maintainers at least fix this oversight.
Accordingly, I withdraw this issue. I do want to bring @1st1 's attention to this, especially regarding asyncio.nop()
. Please close this issue at your convenience.
from asyncio.
Closing this. It was an interesting discussion! I'll add, as I close it, that I made similar decisions implementing async.Queue. At first I wanted any statement in a coroutine like yield from q.get()
or yield from q.put(data)
to definitely yield to the scheduler and unblock any other waiting coroutine. Guido and Nikolay convinced me that it was better for q.get()
and q.put()
to take a fast path if possible and not unblock all waiting coroutines. In real life, coroutines do I/O and yield to the scheduler while they wait for the I/O to complete, and that naturally causes the sort of interleaved execution you expected in your code example.
from asyncio.
Thanks for adding your explanation @ajdavis
I agree that all is fine given the presence of fast path functions such as Lock.locked()
that can predict whether another coroutine will yield or take the fast path.
The anomaly of asyncio.sleep(0)
does remain and I hope some day a asyncio.nop()
is added or at least the behavior of sleep(0)
is documented.
Thanks!
from asyncio.
Related Issues (20)
- StreamReader read with an exception '..incoming data' HOT 2
- Proposal: Rename ensure_future to create_task HOT 32
- asyncio.create_subprocess_exec with IO redirection hangs if no global loop set HOT 2
- Can't receive replies to multicast UDP packets HOT 6
- How can I have multiple asyncio processes listening on the same port? HOT 5
- NameError in sslproto.py on _fatal_error. HOT 4
- SSL socket exhaustion? HOT 10
- subprocess._loop deleted too soon causing exception when trying to read from pipe HOT 5
- SSL server sockets that haven't completed handshake lead to log spew on loop close HOT 4
- RuntimeError: Cannot pause_reading() when closing HOT 2
- Python asyncio doc seems not match the procedure when running HOT 1
- Question: what's the morale behind having a `asyncio.Future`? HOT 2
- How to keep session alive when using async websockets? HOT 1
- Wrapping an existing transport in SSL HOT 2
- asyncio get_extra_info() throws exception (Python 3.5.3) HOT 3
- Add Codacy to check for Issues.
- Migrating from python 3.4 to 3.5 error HOT 1
- `loop.add_reader` and `<<EOF` HOT 1
- Why asyncio.transport.write() function don`t send data until I use transport.close() or stop the event loop.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from asyncio.