forked from goodboy/tractor
Always raise remote (cancelled) error if set
Previously we weren't raising a remote error if the local scope was cancelled during a call to `Context.result()` which is problematic if the caller WAS NOT the requester for said remote cancellation; in that case we still want a `ContextCancelled` raised with the `.canceller: str` set to the cancelling actor uid. Further fix a naming bug where the (seemingly older) `._remote_err` was being set to such an error instead of `._remote_error` XDmultihomed
parent
919e462f88
commit
575a24adf1
|
@ -102,10 +102,14 @@ class Context:
|
||||||
_remote_error: BaseException | None = None
|
_remote_error: BaseException | None = None
|
||||||
|
|
||||||
# cancellation state
|
# cancellation state
|
||||||
_cancel_called: bool = False
|
_cancel_called: bool = False # did WE cancel the far end?
|
||||||
_cancelled_remote: tuple | None = None
|
_cancelled_remote: tuple[str, str] | None = None
|
||||||
_cancel_msg: str | None = None
|
_cancel_msg: str | None = None
|
||||||
_scope: trio.CancelScope | None = None
|
_scope: trio.CancelScope | None = None
|
||||||
|
|
||||||
|
# NOTE: this is set by the `.devx._debug` machinery
|
||||||
|
# to indicate whether code in `._runtime` should handle
|
||||||
|
# cancelled context crashes in the pdbp REPL.
|
||||||
_enter_debugger_on_cancel: bool = True
|
_enter_debugger_on_cancel: bool = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -207,7 +211,7 @@ class Context:
|
||||||
# XXX: set the remote side's error so that after we cancel
|
# XXX: set the remote side's error so that after we cancel
|
||||||
# whatever task is the opener of this context it can raise
|
# whatever task is the opener of this context it can raise
|
||||||
# that error as the reason.
|
# that error as the reason.
|
||||||
self._remote_error = error
|
self._remote_error: BaseException = error
|
||||||
|
|
||||||
# always record the remote actor's uid since its cancellation
|
# always record the remote actor's uid since its cancellation
|
||||||
# state is directly linked to ours (the local one).
|
# state is directly linked to ours (the local one).
|
||||||
|
@ -488,11 +492,7 @@ class Context:
|
||||||
assert self._portal, "Context.result() can not be called from callee!"
|
assert self._portal, "Context.result() can not be called from callee!"
|
||||||
assert self._recv_chan
|
assert self._recv_chan
|
||||||
|
|
||||||
# from . import _debug
|
if re := self._remote_error:
|
||||||
# await _debug.breakpoint()
|
|
||||||
|
|
||||||
re = self._remote_error
|
|
||||||
if re:
|
|
||||||
self._maybe_raise_remote_err(re)
|
self._maybe_raise_remote_err(re)
|
||||||
return re
|
return re
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ class Context:
|
||||||
while True:
|
while True:
|
||||||
msg = await self._recv_chan.receive()
|
msg = await self._recv_chan.receive()
|
||||||
try:
|
try:
|
||||||
self._result = msg['return']
|
self._result: Any = msg['return']
|
||||||
|
|
||||||
# NOTE: we don't need to do this right?
|
# NOTE: we don't need to do this right?
|
||||||
# XXX: only close the rx mem chan AFTER
|
# XXX: only close the rx mem chan AFTER
|
||||||
|
@ -516,6 +516,21 @@ class Context:
|
||||||
# await self._recv_chan.aclose()
|
# await self._recv_chan.aclose()
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# NOTE: we get here if the far end was
|
||||||
|
# `ContextCancelled` in 2 cases:
|
||||||
|
# - we requested the cancellation and thus
|
||||||
|
# SHOULD NOT raise that far end error,
|
||||||
|
# - WE DID NOT REQUEST that cancel and thus
|
||||||
|
# SHOULD RAISE HERE!
|
||||||
|
except trio.Cancelled:
|
||||||
|
if not self._cancel_called:
|
||||||
|
raise self._remote_error
|
||||||
|
else:
|
||||||
|
# if we DID request the cancel we simply
|
||||||
|
# continue as normal.
|
||||||
|
raise
|
||||||
|
|
||||||
except KeyError: # as msgerr:
|
except KeyError: # as msgerr:
|
||||||
|
|
||||||
if 'yield' in msg:
|
if 'yield' in msg:
|
||||||
|
@ -537,7 +552,7 @@ class Context:
|
||||||
) # from msgerr
|
) # from msgerr
|
||||||
|
|
||||||
err = self._maybe_raise_remote_err(err)
|
err = self._maybe_raise_remote_err(err)
|
||||||
self._remote_err = err
|
self._remote_error = err
|
||||||
|
|
||||||
return self._remote_error or self._result
|
return self._remote_error or self._result
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue