tractor icon indicating copy to clipboard operation
tractor copied to clipboard

`taskman`: an initial prototype for a `trio.Nursery`-like per-task-scope-manager (maybe via a user defined single-yield-generator function?) 😎

Open goodboy opened this issue 2 years ago • 0 comments

As per some discussion in the trio gitter and starting something toward #22 and supporting our debugger crash mode from within a trio-compat task nursery.


Idea: a trio.Nursery API for optionally allowing a user to define a per-task manager

But why?

Well if you wanted any of the following (some of which are implemented in the module script in this patch):

  • generally gain access to lower level trio.Nursery "internals" for any per-task oriented purpose.
  • some way to wrap your own "task handle" so you could do things like waiting on a task to finish and get its result.
  • allow hooking into each task's exit/teardown (phase) for the purposes of debugging crashes, (unexpected) cancels or just generally tracing the trio per task control flow.
  • enable more granular task supervision strategies like one_for_one from erlang/elixir and friends.

ToDo:

  • [x] offer a task_manager context-manager-as-generator API such that the current TaskOutcome struct is not tied to the internals of the ScopePerTaskNursery.start_soon() implementation.

    • [x] ideally the outcome: Outcome = yield (cs, ..) is delivered to the user defined mngr ~~via a Outcome.send(mngr) call~~ such that only raw trio (dependency) internal types are provided to the user for wrapping / adjusting.
      • NOTE: didn't use Outcome.send() bc it would send the underlying value, not the outcome instance; not sure if that's best?
  • [ ] way better naming since most of this was whipped up on the first try and getting good names is probably going to be tricky :joy:

    • [x] @task_manager is maybe better? @task_scope_manager?
    • [x] ScopePerTaskNursery is terrible.. how about TaskScopedNursery?
      • now i'm thinking you don't need much at all, TaskManagerNursery?
    • [x] TaskOutcome.unwrap() seems wrong, despite it being an example of a user defined handle.
      • [x] @Fuyukai suggested .wait_for_result() which is a lot more pythonic in terms of plain-ol'-simple-semantics :surfer:
      • ~~maybe .unwind() is more descriptive? as in unwinding the outcome from the task would imply you both have to:~~
        • wait for the result or error from the underlying task
        • retrieve that outcome's value or raise it's error by unwrapping/boxing?
        • stack unwinding is normally synonymous with the end of a function call and the subsequent popping of the stack ..?
      • the nixed above ends up going down the rabbit hole of describing an imperative lang in terms of lower level fp abstractions which is not only confusing but a bit moot: we don't need to hear math about stuff we can't change in (python and) the semantics of a method..:joy:
  • [ ] test the waters in trio core for interest in this idea

    • [x] had a decent discussion on it with the anyio author and njs but don't think they understood what i was proposing (hence this proto :joy:)
    • [ ] the main spot to start digging into how this might be implemented inside trio's scheduler would be about here: https://github.com/python-trio/trio/blob/master/trio/_core/_run.py#L1601 since this is where the nursery-global cancel scope's CancelStatus is activated on the currently spawning task.
      • obviously it's going to require quite a bit of reworking to try and offer the generator-style @cancel_scope_manager thing because we'll need to call __enter__/__exit__ from two different Runner methods -> .spawn_impl() and .task_exited()
    • [ ] probably just eventually accept that no-one will comment on this PR (nor care?) and it'll get relegated to our trionics secret sauces pantry yet again :joy:
  • [ ] figure out if it's possible to swap in this open_nursery() for all uses of trio.open_nursery() when our users enable debug mode :joy:

    • pretty sure we can do it at appropriate spots during (sub)actor boot?
      • root: https://github.com/goodboy/tractor/blob/master/tractor/_root.py#L135
      • child: https://github.com/goodboy/tractor/blob/master/tractor/_entry.py#L97

Hopefully much more to come!

goodboy avatar May 17 '23 18:05 goodboy