Reduce "ignore cases" script to `trio`-only

Remove all the `tractor` usage (with IPC ctxs) and just get us
a min-reproducing-example with a multi-task-single `trio.Lock`.
The wrapping test suite runs the exact same with an ignore case and
an `.xfail()` for when we let the `trio.WouldBlock` be unmasked.
cancelled_masking_guards
Tyler Goodlet 2025-09-07 18:47:10 -04:00
parent 9c6b90ef04
commit 07781e38cd
1 changed files with 43 additions and 55 deletions

View File

@ -1,3 +1,6 @@
from contextlib import (
asynccontextmanager as acm,
)
from functools import partial
import tractor
@ -8,29 +11,34 @@ log = tractor.log.get_logger(
name=__name__
)
_lock: trio.Lock|None = None
@acm
async def acquire_singleton_lock(
_lock = trio.Lock(),
) -> None:
global _lock
if _lock is None:
log.info('Allocating LOCK')
_lock = trio.Lock()
log.info('TRYING TO LOCK ACQUIRE')
await _lock.acquire()
async with _lock:
log.info('ACQUIRED')
yield _lock
log.info('RELEASED')
@tractor.context
async def acquire_actor_global_lock(
ctx: tractor.Context,
ignore_special_cases: bool,
async def hold_lock_forever(
task_status=trio.TASK_STATUS_IGNORED
):
if not ignore_special_cases:
from tractor.trionics import _taskc
_taskc._mask_cases.clear()
await acquire_singleton_lock()
await ctx.started('locked')
# block til cancelled
async with (
tractor.trionics.maybe_raise_from_masking_exc(),
acquire_singleton_lock() as lock,
):
task_status.started(lock)
await trio.sleep_forever()
@ -38,57 +46,37 @@ async def main(
ignore_special_cases: bool,
loglevel: str = 'info',
debug_mode: bool = True,
_fail_after: float = 2,
):
tractor.log.get_console_log(level=loglevel)
with trio.fail_after(_fail_after):
async with (
tractor.trionics.collapse_eg(),
tractor.open_nursery(
debug_mode=debug_mode,
loglevel=loglevel,
) as an,
trio.open_nursery() as tn,
# tractor.trionics.maybe_raise_from_masking_exc()
# ^^^ XXX NOTE, interestingly putting the unmasker
# here does not exhibit the same behaviour ??
):
ptl = await an.start_actor(
'locker',
enable_modules=[__name__],
if not ignore_special_cases:
from tractor.trionics import _taskc
_taskc._mask_cases.clear()
_lock = await tn.start(
hold_lock_forever,
)
with trio.move_on_after(0.2):
await tn.start(
hold_lock_forever,
)
async def _open_ctx(
task_status=trio.TASK_STATUS_IGNORED,
):
async with ptl.open_context(
acquire_actor_global_lock,
ignore_special_cases=ignore_special_cases,
) as pair:
task_status.started(pair)
await trio.sleep_forever()
first_ctx, first = await tn.start(_open_ctx,)
assert first == 'locked'
with trio.move_on_after(0.5):# as cs:
await _open_ctx()
# await tractor.pause()
print('cancelling first IPC ctx!')
await first_ctx.cancel()
await ptl.cancel_actor()
# await tractor.pause()
tn.cancel_scope.cancel()
# XXX, manual test as script
if __name__ == '__main__':
tractor.log.get_console_log(level='info')
for case in [False, True]:
for case in [True, False]:
log.info(
f'\n'
f'------ RUNNING SCRIPT TRIAL ------\n'
f'child_errors_midstream: {case!r}\n'
f'ignore_special_cases: {case!r}\n'
)
trio.run(partial(
main,