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
parent
9c6b90ef04
commit
07781e38cd
|
@ -1,3 +1,6 @@
|
||||||
|
from contextlib import (
|
||||||
|
asynccontextmanager as acm,
|
||||||
|
)
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
import tractor
|
import tractor
|
||||||
|
@ -8,87 +11,72 @@ log = tractor.log.get_logger(
|
||||||
name=__name__
|
name=__name__
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_lock: trio.Lock|None = None
|
||||||
|
|
||||||
|
|
||||||
|
@acm
|
||||||
async def acquire_singleton_lock(
|
async def acquire_singleton_lock(
|
||||||
_lock = trio.Lock(),
|
|
||||||
) -> None:
|
) -> None:
|
||||||
|
global _lock
|
||||||
|
if _lock is None:
|
||||||
|
log.info('Allocating LOCK')
|
||||||
|
_lock = trio.Lock()
|
||||||
|
|
||||||
log.info('TRYING TO LOCK ACQUIRE')
|
log.info('TRYING TO LOCK ACQUIRE')
|
||||||
await _lock.acquire()
|
async with _lock:
|
||||||
log.info('ACQUIRED')
|
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:
|
async with (
|
||||||
from tractor.trionics import _taskc
|
tractor.trionics.maybe_raise_from_masking_exc(),
|
||||||
_taskc._mask_cases.clear()
|
acquire_singleton_lock() as lock,
|
||||||
|
):
|
||||||
await acquire_singleton_lock()
|
task_status.started(lock)
|
||||||
await ctx.started('locked')
|
await trio.sleep_forever()
|
||||||
|
|
||||||
# block til cancelled
|
|
||||||
await trio.sleep_forever()
|
|
||||||
|
|
||||||
|
|
||||||
async def main(
|
async def main(
|
||||||
ignore_special_cases: bool,
|
ignore_special_cases: bool,
|
||||||
loglevel: str = 'info',
|
loglevel: str = 'info',
|
||||||
debug_mode: bool = True,
|
debug_mode: bool = True,
|
||||||
|
|
||||||
_fail_after: float = 2,
|
|
||||||
):
|
):
|
||||||
tractor.log.get_console_log(level=loglevel)
|
async with (
|
||||||
|
trio.open_nursery() as tn,
|
||||||
|
|
||||||
with trio.fail_after(_fail_after):
|
# tractor.trionics.maybe_raise_from_masking_exc()
|
||||||
async with (
|
# ^^^ XXX NOTE, interestingly putting the unmasker
|
||||||
tractor.trionics.collapse_eg(),
|
# here does not exhibit the same behaviour ??
|
||||||
tractor.open_nursery(
|
):
|
||||||
debug_mode=debug_mode,
|
if not ignore_special_cases:
|
||||||
loglevel=loglevel,
|
from tractor.trionics import _taskc
|
||||||
) as an,
|
_taskc._mask_cases.clear()
|
||||||
trio.open_nursery() as tn,
|
|
||||||
):
|
_lock = await tn.start(
|
||||||
ptl = await an.start_actor(
|
hold_lock_forever,
|
||||||
'locker',
|
)
|
||||||
enable_modules=[__name__],
|
with trio.move_on_after(0.2):
|
||||||
|
await tn.start(
|
||||||
|
hold_lock_forever,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _open_ctx(
|
tn.cancel_scope.cancel()
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
# XXX, manual test as script
|
# XXX, manual test as script
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
tractor.log.get_console_log(level='info')
|
tractor.log.get_console_log(level='info')
|
||||||
for case in [False, True]:
|
for case in [True, False]:
|
||||||
log.info(
|
log.info(
|
||||||
f'\n'
|
f'\n'
|
||||||
f'------ RUNNING SCRIPT TRIAL ------\n'
|
f'------ RUNNING SCRIPT TRIAL ------\n'
|
||||||
f'child_errors_midstream: {case!r}\n'
|
f'ignore_special_cases: {case!r}\n'
|
||||||
)
|
)
|
||||||
trio.run(partial(
|
trio.run(partial(
|
||||||
main,
|
main,
|
||||||
|
|
Loading…
Reference in New Issue