forked from goodboy/tractor
1
0
Fork 0

Support `maybe_wait_for_debugger(header_msg: str)`

Allow callers to stick in a header to the `.pdb()` level emitted msg(s)
such that any "waiting status" content is only shown if the caller
actually get's blocked waiting for the debug lock; use it inside the
`._spawn` sub-process reaper call.

Also, return early if `Lock.global_actor_in_debug == None` and thus
only enter the poll loop when actually needed, consequently raise
if we fall through the loop without acquisition.
modden_spawn_from_client_req
Tyler Goodlet 2024-02-22 15:08:10 -05:00
parent de1843dc84
commit fc72d75061
2 changed files with 50 additions and 28 deletions

View File

@ -541,13 +541,14 @@ async def trio_proc(
with trio.move_on_after(0.5): with trio.move_on_after(0.5):
await proc.wait() await proc.wait()
log.pdb(
'Delaying subproc reaper while debugger locked..'
)
await maybe_wait_for_debugger( await maybe_wait_for_debugger(
child_in_debug=_runtime_vars.get( child_in_debug=_runtime_vars.get(
'_debug_mode', False '_debug_mode', False
), ),
header_msg=(
'Delaying subproc reaper while debugger locked..\n'
),
# TODO: need a diff value then default? # TODO: need a diff value then default?
# poll_steps=9999999, # poll_steps=9999999,
) )

View File

@ -999,6 +999,8 @@ async def maybe_wait_for_debugger(
poll_delay: float = 0.1, poll_delay: float = 0.1,
child_in_debug: bool = False, child_in_debug: bool = False,
header_msg: str = '',
) -> None: ) -> None:
if ( if (
@ -1007,6 +1009,8 @@ async def maybe_wait_for_debugger(
): ):
return return
msg: str = header_msg
if ( if (
is_root_process() is_root_process()
): ):
@ -1016,13 +1020,13 @@ async def maybe_wait_for_debugger(
# will make the pdb repl unusable. # will make the pdb repl unusable.
# Instead try to wait for pdb to be released before # Instead try to wait for pdb to be released before
# tearing down. # tearing down.
sub_in_debug: tuple[str, str] | None = None sub_in_debug: tuple[str, str]|None = Lock.global_actor_in_debug
debug_complete: trio.Event|None = Lock.no_remote_has_tty
for istep in range(poll_steps):
if sub_in_debug := Lock.global_actor_in_debug: if sub_in_debug := Lock.global_actor_in_debug:
log.pdb( msg += (
f'Lock in use by {sub_in_debug}' 'Debug `Lock` in use by subactor\n'
f'|_{sub_in_debug}\n'
) )
# TODO: could this make things more deterministic? # TODO: could this make things more deterministic?
# wait to see if a sub-actor task will be # wait to see if a sub-actor task will be
@ -1030,34 +1034,45 @@ async def maybe_wait_for_debugger(
# tick? # tick?
# XXX => but it doesn't seem to work.. # XXX => but it doesn't seem to work..
# await trio.testing.wait_all_tasks_blocked(cushion=0) # await trio.testing.wait_all_tasks_blocked(cushion=0)
else:
log.pdb(
msg
+
'Root immediately acquired debug TTY LOCK'
)
return
for istep in range(poll_steps):
debug_complete: trio.Event|None = Lock.no_remote_has_tty
if ( if (
debug_complete debug_complete
and not debug_complete.is_set() and not debug_complete.is_set()
and sub_in_debug is not None and sub_in_debug is not None
): ):
log.pdb( log.pdb(
'Root has errored but pdb is in use by child\n' msg
'Waiting on tty lock to release..\n' +
f'uid: {sub_in_debug}\n' 'Root is waiting on tty lock to release..\n'
) )
await debug_complete.wait() await debug_complete.wait()
log.pdb( log.pdb(
f'Child subactor released debug lock!\n' f'Child subactor released debug lock:'
f'uid: {sub_in_debug}\n' f'|_{sub_in_debug}\n'
) )
if debug_complete.is_set():
break
# is no subactor locking debugger currently? # is no subactor locking debugger currently?
elif ( if (
sub_in_debug is None
and (
debug_complete is None debug_complete is None
or sub_in_debug is None or debug_complete.is_set()
)
): ):
log.pdb( log.pdb(
'Root acquired debug TTY LOCK from child\n' msg
f'uid: {sub_in_debug}' +
'Root acquired tty lock!'
) )
break break
@ -1073,8 +1088,14 @@ async def maybe_wait_for_debugger(
with trio.CancelScope(shield=True): with trio.CancelScope(shield=True):
await trio.sleep(poll_delay) await trio.sleep(poll_delay)
continue continue
# fallthrough on failure to acquire..
else: else:
log.pdb('Root acquired debug TTY LOCK') raise RuntimeError(
msg
+
'Root actor failed to acquire debug lock?'
)
# else: # else:
# # TODO: non-root call for #320? # # TODO: non-root call for #320?