Just set flag for use-after-closed service nursery calls

less_logging
Tyler Goodlet 2021-10-06 15:53:44 -04:00
parent 10f66e5141
commit 1f0cc15675
1 changed files with 15 additions and 9 deletions

View File

@ -612,6 +612,8 @@ class Actor:
# TODO: once https://github.com/python-trio/trio/issues/467 gets # TODO: once https://github.com/python-trio/trio/issues/467 gets
# worked out we'll likely want to use that! # worked out we'll likely want to use that!
msg = None msg = None
nursery_cancelled_before_task: bool = False
log.runtime(f"Entering msg loop for {chan} from {chan.uid}") log.runtime(f"Entering msg loop for {chan} from {chan.uid}")
try: try:
with trio.CancelScope(shield=shield) as loop_cs: with trio.CancelScope(shield=shield) as loop_cs:
@ -692,10 +694,16 @@ class Actor:
# spin up a task for the requested function # spin up a task for the requested function
log.runtime(f"Spawning task for {func}") log.runtime(f"Spawning task for {func}")
assert self._service_n assert self._service_n
try:
cs = await self._service_n.start( cs = await self._service_n.start(
partial(_invoke, self, cid, chan, func, kwargs), partial(_invoke, self, cid, chan, func, kwargs),
name=funcname, name=funcname,
) )
except RuntimeError:
# avoid reporting a benign race condition
# during actor runtime teardown.
nursery_cancelled_before_task = True
# never allow cancelling cancel requests (results in # never allow cancelling cancel requests (results in
# deadlock and other weird behaviour) # deadlock and other weird behaviour)
if func != self.cancel: if func != self.cancel:
@ -741,14 +749,12 @@ class Actor:
log.runtime(f'channel from {chan.uid} closed abruptly:\n{chan}') log.runtime(f'channel from {chan.uid} closed abruptly:\n{chan}')
except (Exception, trio.MultiError) as err: except (Exception, trio.MultiError) as err:
if ( if nursery_cancelled_before_task:
isinstance(err, RuntimeError) and sn = self._service_n
self._service_n.cancel_scope.cancel_called assert sn and sn.cancel_scope.cancel_called
):
log.cancel( log.cancel(
f'Service nursery cancelled before it handled {funcname}' f'Service nursery cancelled before it handled {funcname}'
) )
else: else:
# ship any "internal" exception (i.e. one from internal # ship any "internal" exception (i.e. one from internal
# machinery not from an rpc task) to parent # machinery not from an rpc task) to parent