-
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
Drop the "main" task via kwarg idea #25
Conversation
Stop worrying about a "main task" in each actor and instead add an additional `ActorNursery.run_in_actor()` method which wraps calls to create an actor and run a lone RPC task inside it. Note this adjusts the public API of `ActorNursery.start_actor()` to drop its `main` kwarg. The dirty deats of making this possible: - each spawned RPC task is now tracked with a specific cancel scope such that when the actor is cancelled all ongoing responders are cancelled before any IPC/channel machinery is closed (turns out that spawning new actors from `outlive_main=True` actors was probably borked before finally getting this working). - make each initial RPC response be a packet which describes the `functype` (eg. `{'functype': 'asyncfunction'}`) allowing for async calls/submissions by client actors (this was required to make `run_in_actor()` work - `Portal._submit()` is the new async method). - hooray we can stop faking "main task" results for daemon actors - add better handling/raising of internal errors caught in the bowels of the `Actor` itself. - drop the rpc spawning nursery; just use the `Actor._root_nursery` - only wait on `_no_more_peers` if there are existing peer channels that are actually still connected. - an `ActorNursery.__aexit__()` now implicitly waits on `Portal.result()` on close for each `run_in_actor()` spawned actor. - handle cancelling partial started actors which haven't yet connected back to the parent Resolves #24
if functype == 'function' or functype == 'asyncfunction': | ||
resp_type = 'return' | ||
elif functype == 'asyncgen': | ||
resp_type = 'yield' |
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.
Have you considered using an enum here instead of strings?
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.
Added #27 for this.
tractor/_actor.py
Outdated
log.debug( | ||
f"Cancelling all tasks for {chan} from {chan.uid}") | ||
scopes = self._rpc_tasks.pop(chan, None) | ||
if scopes: |
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.
If you do scopes = self._rpc_tasks.pop(chan, ())
instead, you can skip the if
.
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.
Good point.
Stop worrying about a "main task" in each actor and instead add an
additional
ActorNursery.run_in_actor()
method which wraps callsto create an actor and run a lone RPC task inside it. Note this
adjusts the public API of
ActorNursery.start_actor()
to dropits
main
kwarg.The dirty deats of making this possible:
that when the actor is cancelled all ongoing responders are cancelled
before any IPC/channel machinery is closed (turns out that spawning
new actors from
outlive_main=True
actors was probably borked beforefinally getting this working).
functype
(eg.{'functype': 'asyncfunction'}
) allowing for asynccalls/submissions by client actors (this was required to make
run_in_actor()
work -Portal._submit()
is the new async method).the
Actor
itself.Actor._root_nursery
_no_more_peers
if there are existing peer channels thatare actually still connected.
ActorNursery.__aexit__()
now implicitly waits onPortal.result()
on closefor each
run_in_actor()
spawned actor.back to the parent
Resolves #24
This will require updates to #11 obviously.
ping @vodik!