Update `._entry` actor status log
Log-report the different types of actor exit conditions including cancel via KBI, error or normal return with varying levels depending on case. Also, start proto-ing out this weird ascii-syntax idea for describing conc system states and implement the first bit in a `nest_from_op()` log-message fmter that joins and indents an obj `repr()` with a tree-like `'>)\n|_'` header.multihost_exs
parent
cb90f3e6ba
commit
4fbd469c33
|
@ -20,7 +20,8 @@ Sub-process entry points.
|
|||
"""
|
||||
from __future__ import annotations
|
||||
from functools import partial
|
||||
# import textwrap
|
||||
import os
|
||||
import textwrap
|
||||
from typing import (
|
||||
Any,
|
||||
TYPE_CHECKING,
|
||||
|
@ -58,7 +59,7 @@ def _mp_main(
|
|||
|
||||
) -> None:
|
||||
'''
|
||||
The routine called *after fork* which invokes a fresh ``trio.run``
|
||||
The routine called *after fork* which invokes a fresh `trio.run()`
|
||||
|
||||
'''
|
||||
actor._forkserver_info = forkserver_info
|
||||
|
@ -96,6 +97,107 @@ def _mp_main(
|
|||
log.info(f"Subactor {actor.uid} terminated")
|
||||
|
||||
|
||||
# TODO: move this func to some kinda `.devx._conc_lang.py` eventually
|
||||
# as we work out our multi-domain state-flow-syntax!
|
||||
def nest_from_op(
|
||||
input_op: str,
|
||||
#
|
||||
# ?TODO? an idea for a syntax to the state of concurrent systems
|
||||
# as a "3-domain" (execution, scope, storage) model and using
|
||||
# a minimal ascii/utf-8 operator-set.
|
||||
#
|
||||
# try not to take any of this seriously yet XD
|
||||
#
|
||||
# > is a "play operator" indicating (CPU bound)
|
||||
# exec/work/ops required at the "lowest level computing"
|
||||
#
|
||||
# execution primititves (tasks, threads, actors..) denote their
|
||||
# lifetime with '(' and ')' since parentheses normally are used
|
||||
# in many langs to denote function calls.
|
||||
#
|
||||
# starting = (
|
||||
# >( opening/starting; beginning of the thread-of-exec (toe?)
|
||||
# (> opened/started, (finished spawning toe)
|
||||
# |_<Task: blah blah..> repr of toe, in py these look like <objs>
|
||||
#
|
||||
# >) closing/exiting/stopping,
|
||||
# )> closed/exited/stopped,
|
||||
# |_<Task: blah blah..>
|
||||
# [OR <), )< ?? ]
|
||||
#
|
||||
# ending = )
|
||||
# >c) cancelling to close/exit
|
||||
# c)> cancelled (caused close), OR?
|
||||
# |_<Actor: ..>
|
||||
# OR maybe "<c)" which better indicates the cancel being
|
||||
# "delivered/returned" / returned" to LHS?
|
||||
#
|
||||
# >x) erroring to eventuall exit
|
||||
# x)> errored and terminated
|
||||
# |_<Actor: ...>
|
||||
#
|
||||
# scopes: supers/nurseries, IPC-ctxs, sessions, perms, etc.
|
||||
# >{ opening
|
||||
# {> opened
|
||||
# }> closed
|
||||
# >} closing
|
||||
#
|
||||
# storage: like queues, shm-buffers, files, etc..
|
||||
# >[ opening
|
||||
# [> opened
|
||||
# |_<FileObj: ..>
|
||||
#
|
||||
# >] closing
|
||||
# ]> closed
|
||||
|
||||
# IPC ops: channels, transports, msging
|
||||
# => req msg
|
||||
# <= resp msg
|
||||
# <=> 2-way streaming (of msgs)
|
||||
# <- recv 1 msg
|
||||
# -> send 1 msg
|
||||
#
|
||||
# TODO: still not sure on R/L-HS approach..?
|
||||
# =>( send-req to exec start (task, actor, thread..)
|
||||
# (<= recv-req to ^
|
||||
#
|
||||
# (<= recv-req ^
|
||||
# <=( recv-resp opened remote exec primitive
|
||||
# <=) recv-resp closed
|
||||
#
|
||||
# )<=c req to stop due to cancel
|
||||
# c=>) req to stop due to cancel
|
||||
#
|
||||
# =>{ recv-req to open
|
||||
# <={ send-status that it closed
|
||||
|
||||
tree_str: str,
|
||||
|
||||
# NOTE: so move back-from-the-left of the `input_op` by
|
||||
# this amount.
|
||||
back_from_op: int = 0,
|
||||
) -> str:
|
||||
'''
|
||||
Depth-increment the input (presumably hierarchy/supervision)
|
||||
input "tree string" below the provided `input_op` execution
|
||||
operator, so injecting a `"\n|_{input_op}\n"`and indenting the
|
||||
`tree_str` to nest content aligned with the ops last char.
|
||||
|
||||
'''
|
||||
return (
|
||||
f'{input_op}\n'
|
||||
+
|
||||
textwrap.indent(
|
||||
tree_str,
|
||||
prefix=(
|
||||
len(input_op)
|
||||
-
|
||||
(back_from_op + 1)
|
||||
) * ' ',
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _trio_main(
|
||||
actor: Actor,
|
||||
*,
|
||||
|
@ -107,7 +209,6 @@ def _trio_main(
|
|||
Entry point for a `trio_run_in_process` subactor.
|
||||
|
||||
'''
|
||||
# __tracebackhide__: bool = True
|
||||
_debug.hide_runtime_frames()
|
||||
|
||||
_state._current_actor = actor
|
||||
|
@ -119,7 +220,6 @@ def _trio_main(
|
|||
|
||||
if actor.loglevel is not None:
|
||||
get_console_log(actor.loglevel)
|
||||
import os
|
||||
actor_info: str = (
|
||||
f'|_{actor}\n'
|
||||
f' uid: {actor.uid}\n'
|
||||
|
@ -128,13 +228,23 @@ def _trio_main(
|
|||
f' loglevel: {actor.loglevel}\n'
|
||||
)
|
||||
log.info(
|
||||
'Started new trio subactor:\n'
|
||||
'Starting new `trio` subactor:\n'
|
||||
+
|
||||
'>\n' # like a "started/play"-icon from super perspective
|
||||
+
|
||||
actor_info,
|
||||
nest_from_op(
|
||||
input_op='>(', # see syntax ideas above
|
||||
tree_str=actor_info,
|
||||
back_from_op=1,
|
||||
)
|
||||
)
|
||||
|
||||
logmeth = log.info
|
||||
exit_status: str = (
|
||||
'Subactor exited\n'
|
||||
+
|
||||
nest_from_op(
|
||||
input_op=')>', # like a "closed-to-play"-icon from super perspective
|
||||
tree_str=actor_info,
|
||||
)
|
||||
)
|
||||
try:
|
||||
if infect_asyncio:
|
||||
actor._infected_aio = True
|
||||
|
@ -143,16 +253,28 @@ def _trio_main(
|
|||
trio.run(trio_main)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
log.cancel(
|
||||
'Actor received KBI\n'
|
||||
logmeth = log.cancel
|
||||
exit_status: str = (
|
||||
'Actor received KBI (aka an OS-cancel)\n'
|
||||
+
|
||||
actor_info
|
||||
nest_from_op(
|
||||
input_op='c)>', # closed due to cancel (see above)
|
||||
tree_str=actor_info,
|
||||
)
|
||||
)
|
||||
except BaseException as err:
|
||||
logmeth = log.error
|
||||
exit_status: str = (
|
||||
'Main actor task crashed during exit?\n'
|
||||
+
|
||||
nest_from_op(
|
||||
input_op='x)>', # closed by error
|
||||
tree_str=actor_info,
|
||||
)
|
||||
)
|
||||
# NOTE since we raise a tb will already be shown on the
|
||||
# console, thus we do NOT use `.exception()` above.
|
||||
raise err
|
||||
|
||||
finally:
|
||||
log.info(
|
||||
'Subactor terminated\n'
|
||||
+
|
||||
'x\n' # like a "crossed-out/killed" from super perspective
|
||||
+
|
||||
actor_info
|
||||
)
|
||||
logmeth(exit_status)
|
||||
|
|
Loading…
Reference in New Issue