Skip to content

Commit 2616f4b

Browse files
committed
Tried out an alt approach for .to_asyncio crashes
This change is masked out now BUT i'm leaving it in for reference. I was debugging a multi-actor fault where the primary source actor was an infected-aio-subactor (`brokerd.ib`) and it seemed like the REPL was only entering on the `trio` side (at a `.open_channel_from()`) and not eventually breaking in the `asyncio.Task`. But, since (changing something?) it seems to be working now, it's just that the `trio` side seems to sometimes handle before the (source/causing and more child-ish) `asyncio`-task, which is a bit odd and not expected.. We could likely refine (maybe with an inter-loop-task REPL lock?) this at some point and ensure a child-`asyncio` task which errors always grabs the REPL **first**? Lowlevel deats/further-todos, - add (masked) `maybe_open_crash_handler()` block around `asyncio.Task` execution with notes about weird parent-addr delivery bug in `test_sync_pause_from_aio_task` * yeah dunno what that's about but made a bug; seems to be IPC serialization of the `TCPAddress` struct somewhere?? - add inter-loop lock TODO for avoiding aio-task clobbering trio-tasks when both crash in debug-mode Also, - change import from `tractor.devx.debug` to `tractor.devx` - adjust `get_logger()` call to use new implicit mod-name detection added to `.log.get_logger()`, i.e. sin `name=__name__`. - some teensie refinements to `open_channel_from()`: * swap return type annotation for to `tuple[LinkedTaskChannel, Any]` (was `Any`). * update doc-string to clarify started-value delivery * add err-log before `.pause()` in what should be an unreachable path. * add todo to swap the `(first, chan)` pair to match that of ctx.. (this commit msg was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
1 parent b5fd2a4 commit 2616f4b

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

tractor/to_asyncio.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
_runtime_vars,
4949
)
5050
from tractor._context import Unresolved
51-
from tractor.devx import debug
51+
from tractor import devx
5252
from tractor.log import (
5353
get_logger,
5454
StackLevelAdapter,
@@ -439,7 +439,23 @@ async def wait_on_coro_final_result(
439439

440440
orig = result = id(coro)
441441
try:
442+
# XXX TODO UGH!
443+
# this seems to break a `test_sync_pause_from_aio_task`
444+
# in a REALLY weird way where a `dict` value for
445+
# `_runtime_vars['_root_addrs']` is delivered from the
446+
# parent actor??
447+
#
448+
# XXX => see masked `.set_trace()` block in
449+
# `Actor.from_parent()`..
450+
#
451+
# with devx.maybe_open_crash_handler(
452+
# # XXX, if trio-side exits (intentionally) we
453+
# # shouldn't care bc it should have its own crash
454+
# # handling logic.
455+
# ignore={TrioTaskExited,},
456+
# ) as _bxerr:
442457
result: Any = await coro
458+
443459
chan._aio_result = result
444460
except BaseException as aio_err:
445461
chan._aio_err = aio_err
@@ -546,7 +562,7 @@ async def wait_on_coro_final_result(
546562
if (
547563
debug_mode()
548564
and
549-
(greenback := debug.maybe_import_greenback(
565+
(greenback := devx.debug.maybe_import_greenback(
550566
force_reload=True,
551567
raise_not_found=False,
552568
))
@@ -946,7 +962,11 @@ async def translate_aio_errors(
946962
except BaseException as _trio_err:
947963
trio_err = chan._trio_err = _trio_err
948964
# await tractor.pause(shield=True) # workx!
949-
entered: bool = await debug._maybe_enter_pm(
965+
966+
# !TODO! we need an inter-loop lock here to avoid aio-tasks
967+
# clobbering trio ones when both crash in debug-mode!
968+
#
969+
entered: bool = await devx.debug._maybe_enter_pm(
950970
trio_err,
951971
api_frame=inspect.currentframe(),
952972
)
@@ -1280,10 +1300,17 @@ async def open_channel_from(
12801300
suppress_graceful_exits: bool = True,
12811301
**target_kwargs,
12821302

1283-
) -> AsyncIterator[Any]:
1303+
) -> AsyncIterator[
1304+
tuple[LinkedTaskChannel, Any]
1305+
]:
12841306
'''
1285-
Open an inter-loop linked task channel for streaming between a target
1286-
spawned ``asyncio`` task and ``trio``.
1307+
Start an `asyncio.Task` as `target()` and open an inter-loop
1308+
(linked) channel for streaming between it and the current
1309+
`trio.Task`.
1310+
1311+
A pair `(chan: LinkedTaskChannel, Any)` is delivered to the caller
1312+
where the 2nd element is the value provided by the
1313+
`asyncio.Task`'s unblocking call to `chan.started_nowait()`.
12871314
12881315
'''
12891316
chan: LinkedTaskChannel = _run_asyncio_task(
@@ -1308,6 +1335,7 @@ async def open_channel_from(
13081335

13091336
# deliver stream handle upward
13101337
yield first, chan
1338+
# ^TODO! swap these!!
13111339
except trio.Cancelled as taskc:
13121340
if cs.cancel_called:
13131341
if isinstance(chan._trio_to_raise, AsyncioCancelled):
@@ -1338,7 +1366,8 @@ async def open_channel_from(
13381366
)
13391367
else:
13401368
# XXX SHOULD NEVER HAPPEN!
1341-
await tractor.pause()
1369+
log.error("SHOULD NEVER GET HERE !?!?")
1370+
await tractor.pause(shield=True)
13421371
else:
13431372
chan._to_trio.close()
13441373

0 commit comments

Comments
 (0)