awaitchannel
awaitchannel copied to clipboard
Is there a way to have select do one and only one action ?
I've been banging my head on this problem for some time, and someone showed this library (which looks quite nice, congrats:) to me, but is is unclear to me if the semantics of select are the same as in Go:
Sometimes, in Go, my code relies on the fact that only one of the channel read or write passed to select actually happened.
If I send one value in channel c1 and another value in channel c2, and then select them both, and e.g. c1's read is chosen by the select and I discard its third return value, is there a guarantee that's c2's value is still available, or is there a possibility that it is lost ?
My problem here is that c2 may have been given to another goroutine, which does not have any access to the context where the third return value of the select call exists, and I may need this coroutine to have access to c2's value.
I hope my question is clear, if not, I'll try my best to clarify.
Hi,
after (id_, r), cases = await select(cases)
it's possible that others have completed and their values are saved into the cases.completed
list – if you don't do a select(cases)
again or retrieve them manually from the cases.completed
list they are gone.
It's based on https://docs.python.org/3/library/asyncio-task.html#asyncio.wait and FIRST_COMPLETED
– but if you can find out whether .completed
is always empty then it could even be removed ;)
Nope, it's really needed and can contain values. So you have to process them (maybe forward/put back in your case?).
Thank you very much for your answers :)
Putting them back is a good idea, but I'm not familiar with asyncio enough to know whether this can be done with a guarantee that no other goroutine is putting something before the value we just read.
Maybe putting the asyncio.wait and the putting back of extraneous values in a critical section ?
I'll work on it. Would you consider a pull request in that sense, maybe with a keyword argument to select so that existing code gets the expected behavior, but go-style select is possible ?
If so, I'll propose the matter to one of my interns.
Cheers,
This was just an educational project for me, I'm happy if it has a use and promotes async Python ;) and there is much room for improvements here, please provide PR's or maintain a fork of this project. The default event loop is slow and it would be interesting to run it on another one - but even then Python has its limits ;) Best regards
For the reference: in my experience getting select
semantics right is the key when implementing go-like channels. Some time ago I had to port my code from Go to Python and for that implemented pygolang which provides working select
including working synchronous select
- select
sends.
Thanks @navytux - I was looking for a working select
and pygolang seems to cut it!
You are welcome, @dumblob; thanks for feedback.