Handle kbi in ctx blocks via `BaseException`

Fixes prior committed tests by more generally handling `BaseExcepion` in
context blocks. Left in the commented concrete list for reference.
fix_kbi_in_ctx_block
Tyler Goodlet 2021-10-04 10:05:40 -04:00
parent 8d79d83ac2
commit bd31f47d5f
1 changed files with 27 additions and 10 deletions
tractor

View File

@ -177,7 +177,6 @@ class Portal:
f"Cancelling all streams with {self.channel.uid}")
for stream in self._streams.copy():
try:
# with trio.CancelScope(shield=True):
await stream.aclose()
except trio.ClosedResourceError:
# don't error the stream having already been closed
@ -294,7 +293,6 @@ class Portal:
async def open_stream_from(
self,
async_gen_func: Callable, # typing: ignore
shield: bool = False,
**kwargs,
) -> AsyncGenerator[ReceiveMsgStream, None]:
@ -318,11 +316,17 @@ class Portal:
# receive only stream
assert functype == 'asyncgen'
ctx = Context(self.channel, cid, _portal=self)
ctx = Context(
self.channel,
cid,
# do we need this to be closed implicitly?
# _recv_chan=recv_chan,
_portal=self
)
try:
# deliver receive only stream
async with ReceiveMsgStream(
ctx, recv_chan, shield=shield
ctx, recv_chan,
) as rchan:
self._streams.add(rchan)
yield rchan
@ -337,13 +341,16 @@ class Portal:
# message right now since there shouldn't be a reason to
# stop and restart the stream, right?
try:
await ctx.cancel()
with trio.CancelScope(shield=True):
await ctx.cancel()
except trio.ClosedResourceError:
# if the far end terminates before we send a cancel the
# underlying transport-channel may already be closed.
log.debug(f'Context {ctx} was already closed?')
log.warning(f'Context {ctx} was already closed?')
# XXX: should this always be done?
# await recv_chan.aclose()
self._streams.remove(rchan)
@asynccontextmanager
@ -408,8 +415,8 @@ class Portal:
# pairs with handling in ``Actor._push_result()``
# recv_chan._ctx = ctx
# await trio.lowlevel.checkpoint()
yield ctx, first
except ContextCancelled as err:
@ -427,9 +434,14 @@ class Portal:
log.debug(f'Context {ctx} cancelled gracefully')
except (
trio.Cancelled,
trio.MultiError,
Exception,
BaseException,
# more specifically, we need to handle:
# Exception,
# trio.Cancelled,
# trio.MultiError,
# KeyboardInterrupt,
) as err:
_err = err
# the context cancels itself on any cancel
@ -440,6 +452,11 @@ class Portal:
raise
finally:
# in the case where a runtime nursery (due to internal bug)
# or a remote actor transmits an error we want to be
# sure we get the error the underlying feeder mem chan.
# if it's not raised here it *should* be raised from the
# msg loop nursery right?
result = await ctx.result()
# though it should be impossible for any tasks