2021-12-13 18:08:32 +00:00
|
|
|
# tractor: structured concurrent "actors".
|
|
|
|
# Copyright 2018-eternity Tyler Goodlet.
|
|
|
|
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
2020-06-28 17:10:02 +00:00
|
|
|
"""
|
2020-12-27 15:55:00 +00:00
|
|
|
Sub-process entry points.
|
2021-12-13 18:08:32 +00:00
|
|
|
|
2020-06-28 17:10:02 +00:00
|
|
|
"""
|
2022-10-09 20:05:40 +00:00
|
|
|
from __future__ import annotations
|
2020-06-28 17:10:02 +00:00
|
|
|
from functools import partial
|
2024-05-06 17:12:44 +00:00
|
|
|
# import textwrap
|
2022-10-09 20:05:40 +00:00
|
|
|
from typing import (
|
|
|
|
Any,
|
|
|
|
TYPE_CHECKING,
|
|
|
|
)
|
2020-06-28 17:10:02 +00:00
|
|
|
|
|
|
|
import trio # type: ignore
|
|
|
|
|
2022-10-09 20:05:40 +00:00
|
|
|
from .log import (
|
|
|
|
get_console_log,
|
|
|
|
get_logger,
|
|
|
|
)
|
2020-06-28 17:10:02 +00:00
|
|
|
from . import _state
|
2024-05-22 19:11:21 +00:00
|
|
|
from .devx import _debug
|
2020-06-29 02:44:16 +00:00
|
|
|
from .to_asyncio import run_as_asyncio_guest
|
2022-10-09 20:05:40 +00:00
|
|
|
from ._runtime import (
|
|
|
|
async_main,
|
|
|
|
Actor,
|
|
|
|
)
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
from ._spawn import SpawnMethodKey
|
2020-06-28 17:10:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
log = get_logger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
def _mp_main(
|
2021-12-02 13:12:20 +00:00
|
|
|
|
2023-09-27 19:19:30 +00:00
|
|
|
actor: Actor,
|
|
|
|
accept_addrs: list[tuple[str, int]],
|
2022-09-15 20:56:50 +00:00
|
|
|
forkserver_info: tuple[Any, Any, Any, Any, Any],
|
2022-10-09 20:05:40 +00:00
|
|
|
start_method: SpawnMethodKey,
|
2022-12-12 18:18:22 +00:00
|
|
|
parent_addr: tuple[str, int] | None = None,
|
2020-07-27 15:03:17 +00:00
|
|
|
infect_asyncio: bool = False,
|
2021-12-02 13:12:20 +00:00
|
|
|
|
2020-06-28 17:10:02 +00:00
|
|
|
) -> None:
|
2021-12-02 13:12:20 +00:00
|
|
|
'''
|
|
|
|
The routine called *after fork* which invokes a fresh ``trio.run``
|
|
|
|
|
|
|
|
'''
|
2020-06-28 17:10:02 +00:00
|
|
|
actor._forkserver_info = forkserver_info
|
|
|
|
from ._spawn import try_set_start_method
|
|
|
|
spawn_ctx = try_set_start_method(start_method)
|
|
|
|
|
|
|
|
if actor.loglevel is not None:
|
|
|
|
log.info(
|
|
|
|
f"Setting loglevel for {actor.uid} to {actor.loglevel}")
|
|
|
|
get_console_log(actor.loglevel)
|
|
|
|
|
|
|
|
assert spawn_ctx
|
|
|
|
log.info(
|
|
|
|
f"Started new {spawn_ctx.current_process()} for {actor.uid}")
|
|
|
|
|
|
|
|
_state._current_actor = actor
|
|
|
|
|
|
|
|
log.debug(f"parent_addr is {parent_addr}")
|
|
|
|
trio_main = partial(
|
2022-08-03 19:29:34 +00:00
|
|
|
async_main,
|
2023-09-27 19:19:30 +00:00
|
|
|
actor=actor,
|
|
|
|
accept_addrs=accept_addrs,
|
2020-06-28 17:10:02 +00:00
|
|
|
parent_addr=parent_addr
|
|
|
|
)
|
|
|
|
try:
|
2020-06-29 02:44:16 +00:00
|
|
|
if infect_asyncio:
|
|
|
|
actor._infected_aio = True
|
|
|
|
run_as_asyncio_guest(trio_main)
|
|
|
|
else:
|
|
|
|
trio.run(trio_main)
|
2020-06-28 17:10:02 +00:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
pass # handle it the same way trio does?
|
2020-12-11 05:15:09 +00:00
|
|
|
|
|
|
|
finally:
|
2024-05-06 17:12:44 +00:00
|
|
|
log.info(f"Subactor {actor.uid} terminated")
|
2020-06-28 17:10:02 +00:00
|
|
|
|
|
|
|
|
2020-07-27 17:55:37 +00:00
|
|
|
def _trio_main(
|
2023-09-27 19:19:30 +00:00
|
|
|
actor: Actor,
|
2020-12-10 19:07:36 +00:00
|
|
|
*,
|
2022-12-12 18:18:22 +00:00
|
|
|
parent_addr: tuple[str, int] | None = None,
|
2020-07-27 15:03:17 +00:00
|
|
|
infect_asyncio: bool = False,
|
2020-09-28 13:24:36 +00:00
|
|
|
|
2021-12-02 13:12:20 +00:00
|
|
|
) -> None:
|
|
|
|
'''
|
|
|
|
Entry point for a `trio_run_in_process` subactor.
|
2020-07-23 17:23:55 +00:00
|
|
|
|
2021-12-02 13:12:20 +00:00
|
|
|
'''
|
2024-05-22 19:11:21 +00:00
|
|
|
# __tracebackhide__: bool = True
|
|
|
|
_debug.hide_runtime_frames()
|
|
|
|
|
2020-06-28 17:10:02 +00:00
|
|
|
_state._current_actor = actor
|
2020-07-27 17:55:37 +00:00
|
|
|
trio_main = partial(
|
2022-08-03 19:29:34 +00:00
|
|
|
async_main,
|
|
|
|
actor,
|
2020-07-27 17:55:37 +00:00
|
|
|
parent_addr=parent_addr
|
|
|
|
)
|
2020-08-03 22:46:18 +00:00
|
|
|
|
2024-03-01 01:01:39 +00:00
|
|
|
if actor.loglevel is not None:
|
|
|
|
get_console_log(actor.loglevel)
|
|
|
|
import os
|
2024-03-05 17:30:09 +00:00
|
|
|
actor_info: str = (
|
2024-03-01 01:01:39 +00:00
|
|
|
f'|_{actor}\n'
|
|
|
|
f' uid: {actor.uid}\n'
|
|
|
|
f' pid: {os.getpid()}\n'
|
|
|
|
f' parent_addr: {parent_addr}\n'
|
|
|
|
f' loglevel: {actor.loglevel}\n'
|
|
|
|
)
|
2024-03-05 17:30:09 +00:00
|
|
|
log.info(
|
2024-05-06 17:12:44 +00:00
|
|
|
'Started new trio subactor:\n'
|
2024-03-05 17:30:09 +00:00
|
|
|
+
|
2024-05-06 17:12:44 +00:00
|
|
|
'>\n' # like a "started/play"-icon from super perspective
|
|
|
|
+
|
|
|
|
actor_info,
|
2024-03-05 17:30:09 +00:00
|
|
|
)
|
2024-03-01 01:01:39 +00:00
|
|
|
|
2020-07-27 17:55:37 +00:00
|
|
|
try:
|
2020-07-27 15:03:17 +00:00
|
|
|
if infect_asyncio:
|
|
|
|
actor._infected_aio = True
|
|
|
|
run_as_asyncio_guest(trio_main)
|
|
|
|
else:
|
|
|
|
trio.run(trio_main)
|
2024-04-02 17:41:52 +00:00
|
|
|
|
2020-07-27 17:55:37 +00:00
|
|
|
except KeyboardInterrupt:
|
2023-09-27 19:19:30 +00:00
|
|
|
log.cancel(
|
2024-03-05 17:30:09 +00:00
|
|
|
'Actor received KBI\n'
|
|
|
|
+
|
|
|
|
actor_info
|
2023-09-27 19:19:30 +00:00
|
|
|
)
|
2020-12-11 05:15:09 +00:00
|
|
|
finally:
|
2024-03-05 17:30:09 +00:00
|
|
|
log.info(
|
2024-04-30 16:15:46 +00:00
|
|
|
'Subactor terminated\n'
|
2024-03-05 17:30:09 +00:00
|
|
|
+
|
2024-05-06 17:12:44 +00:00
|
|
|
'x\n' # like a "crossed-out/killed" from super perspective
|
|
|
|
+
|
2024-03-05 17:30:09 +00:00
|
|
|
actor_info
|
|
|
|
)
|