forked from goodboy/tractor
Add tty lock acquire ctx mngr
parent
d30ce96740
commit
4b2710b8a5
|
@ -5,7 +5,7 @@ Multi-core debugging for da peeps!
|
||||||
import bdb
|
import bdb
|
||||||
import sys
|
import sys
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager as acm
|
||||||
from typing import Tuple, Optional, Callable, AsyncIterator
|
from typing import Tuple, Optional, Callable, AsyncIterator
|
||||||
|
|
||||||
import tractor
|
import tractor
|
||||||
|
@ -122,7 +122,7 @@ class PdbwTeardown(pdbpp.Pdb):
|
||||||
# break
|
# break
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@acm
|
||||||
async def _acquire_debug_lock(
|
async def _acquire_debug_lock(
|
||||||
uid: Tuple[str, str]
|
uid: Tuple[str, str]
|
||||||
|
|
||||||
|
@ -542,8 +542,34 @@ async def _maybe_enter_pm(err):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
async def maybe_wait_for_debugger() -> None:
|
@acm
|
||||||
|
async def acquire_debug_lock(
|
||||||
|
subactor: Actor,
|
||||||
|
) -> None:
|
||||||
|
'''
|
||||||
|
Grab root's debug lock on entry, release on exit.
|
||||||
|
|
||||||
|
'''
|
||||||
|
async with trio.open_nursery() as n:
|
||||||
|
cs = await n.start(
|
||||||
|
wait_for_parent_stdin_hijack,
|
||||||
|
subactor,
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
cs.cancel()
|
||||||
|
|
||||||
|
|
||||||
|
async def maybe_wait_for_debugger(
|
||||||
|
poll_steps: int = 2,
|
||||||
|
poll_delay: float = 0.1,
|
||||||
|
) -> None:
|
||||||
|
|
||||||
|
if not _state.debug_mode():
|
||||||
|
return
|
||||||
|
|
||||||
|
if (
|
||||||
|
is_root_process()
|
||||||
|
):
|
||||||
global _no_remote_has_tty, _global_actor_in_debug, _wait_all_tasks_lock
|
global _no_remote_has_tty, _global_actor_in_debug, _wait_all_tasks_lock
|
||||||
|
|
||||||
# If we error in the root but the debugger is
|
# If we error in the root but the debugger is
|
||||||
|
@ -552,20 +578,10 @@ async def maybe_wait_for_debugger() -> None:
|
||||||
# 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.
|
||||||
if (
|
|
||||||
_state.debug_mode() or
|
|
||||||
is_root_process()
|
|
||||||
):
|
|
||||||
|
|
||||||
# TODO: could this make things more deterministic?
|
|
||||||
# wait to see if a sub-actor task will be
|
|
||||||
# scheduled and grab the tty lock on the next
|
|
||||||
# tick?
|
|
||||||
# await trio.testing.wait_all_tasks_blocked()
|
|
||||||
|
|
||||||
sub_in_debug = None
|
sub_in_debug = None
|
||||||
|
|
||||||
for _ in range(2):
|
for _ in range(poll_steps):
|
||||||
|
|
||||||
if _global_actor_in_debug:
|
if _global_actor_in_debug:
|
||||||
sub_in_debug = tuple(_global_actor_in_debug)
|
sub_in_debug = tuple(_global_actor_in_debug)
|
||||||
|
@ -574,7 +590,7 @@ async def maybe_wait_for_debugger() -> None:
|
||||||
'Root polling for debug')
|
'Root polling for debug')
|
||||||
|
|
||||||
with trio.CancelScope(shield=True):
|
with trio.CancelScope(shield=True):
|
||||||
await trio.sleep(0.1)
|
await trio.sleep(poll_delay)
|
||||||
|
|
||||||
# TODO: could this make things more deterministic? wait
|
# TODO: could this make things more deterministic? wait
|
||||||
# to see if a sub-actor task will be scheduled and grab
|
# to see if a sub-actor task will be scheduled and grab
|
||||||
|
@ -594,7 +610,7 @@ async def maybe_wait_for_debugger() -> None:
|
||||||
|
|
||||||
await debug_complete.wait()
|
await debug_complete.wait()
|
||||||
|
|
||||||
await trio.sleep(0.1)
|
await trio.sleep(poll_delay)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
log.warning(
|
log.warning(
|
||||||
|
|
Loading…
Reference in New Issue