Add `Context` cancel message and debug toggle flag

In the case of a callee-side context cancelling itself it can be handy
to let the caller-side task know (even if through logging) that the
cancel was due to some known reason. Make `.cancel()` accept such
a message on the callee side and have it included in the
`._runtime._invoke()` raised `ContextCancelled` emission.

Also add a `Context._trigger_debugger_on_cancel: bool` flag which can be
set to `False` to avoid the debugger post-mortem crash mode from
engaging on cross-context tasks which cancel themselves for a known
reason (as is needed for blocked tasks in the debug TTY-lock machinery).
debug_lock_blocking
Tyler Goodlet 2022-10-11 12:17:35 -04:00
parent dfdad4d1fa
commit 1c480e6c92
1 changed files with 12 additions and 2 deletions

View File

@ -371,6 +371,8 @@ class Context:
# status flags # status flags
_cancel_called: bool = False _cancel_called: bool = False
_cancel_msg: Optional[str] = None
_trigger_debugger_on_cancel: bool = True
_started_called: bool = False _started_called: bool = False
_started_received: bool = False _started_received: bool = False
_stream_opened: bool = False _stream_opened: bool = False
@ -452,7 +454,11 @@ class Context:
if not self._scope_nursery._closed: # type: ignore if not self._scope_nursery._closed: # type: ignore
self._scope_nursery.start_soon(raiser) self._scope_nursery.start_soon(raiser)
async def cancel(self) -> None: async def cancel(
self,
msg: Optional[str] = None,
) -> None:
''' '''
Cancel this inter-actor-task context. Cancel this inter-actor-task context.
@ -461,6 +467,8 @@ class Context:
''' '''
side = 'caller' if self._portal else 'callee' side = 'caller' if self._portal else 'callee'
if msg:
assert side == 'callee', 'Only callee side can provide cancel msg'
log.cancel(f'Cancelling {side} side of context to {self.chan.uid}') log.cancel(f'Cancelling {side} side of context to {self.chan.uid}')
@ -497,8 +505,10 @@ class Context:
log.cancel( log.cancel(
"Timed out on cancelling remote task " "Timed out on cancelling remote task "
f"{cid} for {self._portal.channel.uid}") f"{cid} for {self._portal.channel.uid}")
# callee side remote task
else: else:
# callee side remote task self._cancel_msg = msg
# TODO: should we have an explicit cancel message # TODO: should we have an explicit cancel message
# or is relaying the local `trio.Cancelled` as an # or is relaying the local `trio.Cancelled` as an