diff --git a/setup.cfg b/setup.cfg index 4923f58..57beda5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ [metadata] name = data_pipe -version = 0.2.0 +version = 0.2.2 requires-python = >=3.8 diff --git a/src/main/data_pipe/basic_trunk.py b/src/main/data_pipe/basic_trunk.py index f151096..8de7723 100644 --- a/src/main/data_pipe/basic_trunk.py +++ b/src/main/data_pipe/basic_trunk.py @@ -23,6 +23,15 @@ from trio._core._run import GLOBAL_RUN_CONTEXT as trio_global_context +@enum.unique +class TrunkMode(enum.Enum): + "framework type" + + TRIO = enum.auto() + CURIO = enum.auto() + ASYNCIO = enum.auto() + + @enum.unique class ExecCode(enum.IntEnum): "server response status code" @@ -150,7 +159,7 @@ async def wait_curio_writable(cls, fd:int) -> None: async def wait_asyncio_readable(cls, fd:int) -> None: loop = asyncio.get_running_loop() future = asyncio.Future() - future.add_done_callback(lambda : loop.remove_reader(fd)) + future.add_done_callback(lambda *args : loop.remove_reader(fd)) loop.add_reader(fd, future.set_result, None) await future @@ -158,7 +167,7 @@ async def wait_asyncio_readable(cls, fd:int) -> None: async def wait_asyncio_writable(cls, fd:int) -> None: loop = asyncio.get_running_loop() future = asyncio.Future() - future.add_done_callback(lambda : loop.remove_writer(fd)) + future.add_done_callback(lambda *args : loop.remove_writer(fd)) loop.add_writer(fd, future.set_result, None) await future @@ -213,17 +222,29 @@ async def this_task(cls) -> int: raise RuntimeError(f"no loop") @classmethod - async def spawn_task(cls, coro_func:CoroutineType, *args) -> "AnyTask": + async def spawn_task(cls, func:CoroutineType, *args) -> "AnyTask": "create and launch new background task" if cls.has_trio_loop(): - return trio.hazmat.spawn_system_task(coro_func, *args) + return trio.hazmat.spawn_system_task(func, *args) elif cls.has_curio_loop(): - return await curio.spawn(coro_func, *args) + return await curio.spawn(func, *args) elif cls.has_asyncio_loop(): - return asyncio.create_task(coro_func(*args)) + return asyncio.create_task(func(*args)) else: raise RuntimeError(f"no loop") + @classmethod + def invoke_main(cls, mode:TrunkMode, func:CoroutineType, *args, **kwargs) -> object: + "create and launch main framework task" + if mode == TrunkMode.TRIO: + return trio.run(func, *args, **kwargs) + elif mode == TrunkMode.CURIO: + return curio.run(func, *args, **kwargs) + elif mode == TrunkMode.ASYNCIO: + return asyncio.run(func(*args, **kwargs)) + else: + raise RuntimeError(f"no mode: {mode}") + @classmethod def default_tracer(cls, token:TrunkToken, diff --git a/src/test/data_pipe_test/basic_trunk_test.py b/src/test/data_pipe_test/basic_trunk_test.py index 86f0d85..9d7d37e 100644 --- a/src/test/data_pipe_test/basic_trunk_test.py +++ b/src/test/data_pipe_test/basic_trunk_test.py @@ -9,15 +9,6 @@ from data_pipe.basic_trunk import * -@enum.unique -class Mode(enum.Enum): - "framework type" - - TRIO = enum.auto() - CURIO = enum.auto() - ASYNCIO = enum.auto() - - class StatusStore(ctypes.Structure): "cross-process value" @@ -58,21 +49,10 @@ async def func_zen(cls, value:int) -> int: return value -def setup_loop(mode:Mode, task:CoroutineType) -> None: - if mode == Mode.TRIO: - trio.run(task) - elif mode == Mode.CURIO: - curio.run(task) - elif mode == Mode.ASYNCIO: - asyncio.run(task()) - else: - raise RuntimeError(f"no mode: {mode}") - - -def verify_trunk(client_mode:Mode, server_mode:Mode, runner_class): +def verify_trunk(client_mode:TrunkMode, server_mode:TrunkMode, runner_class): runner_name = runner_class.__name__ - print(f"runner_class={runner_name} :: client_mode={client_mode} server_mode={server_mode}") + print(f"runner={runner_name} :: client={client_mode.name} server={server_mode.name}") counter = StatusStore.make() assert counter.value == 0 @@ -102,10 +82,10 @@ async def client_task(): await basic_trunk.invoke(RPC.func_zen, 3) def server_main(): - setup_loop(server_mode, server_task) + BasicTrunk.invoke_main(server_mode, server_task) def client_main(): - setup_loop(client_mode, client_task) + BasicTrunk.invoke_main(client_mode, client_task) server_runner = runner_class(target=server_main) client_runner = runner_class(target=client_main) @@ -131,6 +111,6 @@ def client_main(): def test_trunk(): print() for runner_class in [threading.Thread, multiprocessing.Process]: - for client_mode in Mode: - for server_mode in Mode: + for client_mode in TrunkMode: + for server_mode in TrunkMode: verify_trunk(client_mode, server_mode, runner_class) diff --git a/tool/github_squash.py b/tool/github_squash.py index 24f91e2..080c00d 100755 --- a/tool/github_squash.py +++ b/tool/github_squash.py @@ -6,7 +6,7 @@ from devrepo import shell -point = "df57d41c8797052f08d3568f7b0159d285735700" +point = "e64fbbdb04f9cd43f7f3e58688c4ac1e2c2bbb45" message = "develop" shell(f"git reset --soft {point}") diff --git a/tool/perform_tox.py b/tool/perform_tox.py index 2c046bb..7c04fab 100755 --- a/tool/perform_tox.py +++ b/tool/perform_tox.py @@ -6,4 +6,5 @@ from devrepo import shell +shell(f"rm -rf .tox") shell(f"tox")