-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trionics #241
Conversation
fbc6905
to
135459c
Compare
4ef9ef6
to
ae13a5e
Compare
c7e03ae
to
c064d4d
Compare
9a69756
to
e5b3eb1
Compare
Oh, right so we'll need to drop 3.8 as well. |
Since it seems we're building out more and more higher level primitives in order to support certain parallel style actor trees and messaging patterns (eg. task broadcast channels), we might as well start a new sub-package for purely `trio` constructions. We hereby dub this the realm of `trionics` (like electronics but for trios instead of electrons). To kick things off, add an `async_enter_all()` concurrent exit-stack-like context manager API which will concurrently spawn a sequence of provided async context managers and deliver their ordered results but with proper support for `trio` cancellation semantics. The stdlib's `AsyncExitStack` is not compatible with nurseries not `trio` tasks (which are cancelled) since as task will be suspended on the stack after push and does not ever hit a checkpoint until the stack is closed.
Trionics improvements from @overclockworked64
|
||
|
||
@acm | ||
async def open_actor_cluster( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be the answer to the process pool question right? looks great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More or less yah.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the last question here is how do we export this?
Should it be top level from tractor import open_actor_cluster
or maybe should be export via something like tractor.builtin
, tractor.extras
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also change async_enter_all
to mass_aenter
, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, <something_aenter()
is interesting, though i wonder if we should try to mimic what contextlib
stack apis offer? Not that any of them have this kind of interface per say. mass_
seems a bit foreign to me.
I think we need to emphasize that the entering is done concurrently, not just that __aenter__()
is being called (which is obviously async). I think in worker pool parlance this is done with something like pool.map()
but the difference here is that we're not running functions and collecting output - it's more of a setup/teardown type thing..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about enter_all_soon()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AsyncExitStack
api for reference.
Fix type annotations
tractor/trionics/_mngrs.py
Outdated
if all(unwrapped.values()): | ||
all_entered.set() | ||
|
||
await trio.sleep_forever() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My one nitpick as a lurker is that with this cancel-to-exit strategy, all managers will exit via an "unclean" path, or in other words, their __aexit__
methods will never be called with (None, None, None)
as arguments.
I'm not sure if that is actually important? It just gives me an itch. Could replace it with an event pretty easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh good point. I don't see any reason not to use an event and you're right about the mngrs themselves then getting expected inputs on different exit conditions.
The api we've made here is actually closer to `asyncio.gather()` but with opening async context managers instead of funcs. Use another event to allow for graceful teardown of children on non-cancellation exits and add a doc string.
Change to `gather_contexts()`, use event for graceful exit
I think we just need a nooz file and this is good to land? |
Let this CI run through and we'll land it. |
Introduces a new sub-package to start exposing all our high(er) level
trio
primitives and goodies.