Skip to content

Commit 653f23a

Browse files
committed
Bump "task-manager(-nursery)" naming, add logging
Namely just renaming any `trio.Nursery` instances to `tn`, the primary `@acm`-API to `.trionics.open_taskman()` and change out all `print()`s for logger instances with 'info' level enabled by the mod-script usage.
1 parent 90db6f2 commit 653f23a

File tree

1 file changed

+42
-23
lines changed

1 file changed

+42
-23
lines changed

tractor/trionics/_supervisor.py

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
# along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

1717
'''
18-
Erlang-style (ish) "one-cancels-one" nursery.
18+
Erlang-style (ish) "one-cancels-one" nursery, what we just call
19+
a "task manager".
1920
2021
'''
2122
from __future__ import annotations
2223
from contextlib import (
2324
asynccontextmanager as acm,
24-
contextmanager as cm,
25+
# contextmanager as cm,
2526
)
2627
from functools import partial
2728
from typing import (
@@ -35,11 +36,17 @@
3536
)
3637
from msgspec import Struct
3738
import trio
38-
from trio._core._run import (
39-
Task,
39+
from trio import (
40+
TaskStatus,
4041
CancelScope,
4142
Nursery,
4243
)
44+
from trio.lowlevel import (
45+
Task,
46+
)
47+
from tractor.log import get_logger
48+
49+
log = get_logger(__name__)
4350

4451

4552
class TaskOutcome(Struct):
@@ -101,7 +108,7 @@ async def wait_for_result(self) -> Any:
101108

102109

103110
class TaskManagerNursery(Struct):
104-
_n: Nursery
111+
_tn: Nursery
105112
_scopes: dict[
106113
Task,
107114
tuple[CancelScope, Outcome]
@@ -127,20 +134,20 @@ async def start_soon(
127134
# assert len(new_tasks) == 1
128135
# task = new_tasks.pop()
129136

130-
n: Nursery = self._n
137+
tn: Nursery = self._tn
131138

132139
sm = self.task_manager
133140
# we do default behavior of a scope-per-nursery
134141
# if the user did not provide a task manager.
135142
if sm is None:
136-
return n.start_soon(async_fn, *args, name=None)
143+
return tn.start_soon(async_fn, *args, name=None)
137144

138-
new_task: Task | None = None
145+
# new_task: Task|None = None
139146
to_return: tuple[Any] | None = None
140147

141148
# NOTE: what do we enforce as a signature for the
142149
# `@task_scope_manager` here?
143-
mngr = sm(nursery=n)
150+
mngr = sm(nursery=tn)
144151

145152
async def _start_wrapped_in_scope(
146153
task_status: TaskStatus[
@@ -190,7 +197,7 @@ async def _start_wrapped_in_scope(
190197
else:
191198
raise RuntimeError(f"{mngr} didn't stop!")
192199

193-
to_return = await n.start(_start_wrapped_in_scope)
200+
to_return = await tn.start(_start_wrapped_in_scope)
194201
assert to_return is not None
195202

196203
# TODO: use the fancy type-check-time type signature stuff from
@@ -222,7 +229,7 @@ def add_task_handle_and_crash_handling(
222229
'''
223230
# if you need it you can ask trio for the task obj
224231
task: Task = trio.lowlevel.current_task()
225-
print(f'Spawning task: {task.name}')
232+
log.info(f'Spawning task: {task.name}')
226233

227234
# User defined "task handle" for more granular supervision
228235
# of each spawned task as needed for their particular usage.
@@ -247,18 +254,27 @@ def add_task_handle_and_crash_handling(
247254
# Adds "crash handling" from `pdbp` by entering
248255
# a REPL on std errors.
249256
except Exception as err:
250-
print(f'{task.name} crashed, entering debugger!')
251257
if debug_mode:
258+
log.exception(
259+
f'{task.name} crashed, entering debugger!'
260+
)
252261
import pdbp
253262
pdbp.xpm()
254-
raise
263+
264+
raise err
255265

256266
finally:
257-
print(f'{task.name} Exitted')
267+
log.info(
268+
f'Task exitted\n'
269+
f')>\n'
270+
f' |_{task}\n'
271+
# ^^TODO? use sclang formatter?
272+
# -[ ] .devx.pformat.nest_from_op()` yo!
273+
)
258274

259275

260276
@acm
261-
async def open_nursery(
277+
async def open_taskman(
262278
task_manager: Generator[Any, Outcome, None] | None = None,
263279

264280
**lowlevel_nursery_kwargs,
@@ -281,7 +297,7 @@ async def ensure_cancelled():
281297

282298
except trio.Cancelled:
283299
task = trio.lowlevel.current_task()
284-
print(f'heyyo ONLY {task.name} was cancelled as expected B)')
300+
log.cancel(f'heyyo ONLY {task.name} was cancelled as expected B)')
285301
assert 0
286302

287303
except BaseException:
@@ -290,30 +306,33 @@ async def ensure_cancelled():
290306

291307
if __name__ == '__main__':
292308

309+
from tractor.log import get_console_log
310+
get_console_log(level='info')
311+
293312
async def main():
294-
async with open_nursery(
313+
async with open_taskman(
295314
task_manager=partial(
296315
add_task_handle_and_crash_handling,
297316
debug_mode=True,
298317
),
299-
) as sn:
318+
) as tm:
300319
for _ in range(3):
301-
outcome, _ = await sn.start_soon(trio.sleep_forever)
320+
outcome, _ = await tm.start_soon(trio.sleep_forever)
302321

303322
# extra task we want to engage in debugger post mortem.
304-
err_outcome, cs = await sn.start_soon(ensure_cancelled)
323+
err_outcome, cs = await tm.start_soon(ensure_cancelled)
305324

306325
val: str = 'yoyoyo'
307-
val_outcome, _ = await sn.start_soon(
326+
val_outcome, _ = await tm.start_soon(
308327
sleep_then_return_val,
309328
val,
310329
)
311330
res = await val_outcome.wait_for_result()
312331
assert res == val
313-
print(f'{res} -> GOT EXPECTED TASK VALUE')
332+
log.info(f'{res} -> GOT EXPECTED TASK VALUE')
314333

315334
await trio.sleep(0.6)
316-
print(
335+
log.cancel(
317336
f'Cancelling and waiting on {err_outcome.lowlevel_task} '
318337
'to CRASH..'
319338
)

0 commit comments

Comments
 (0)