I have a nursery that I want to cancel at t + 2, where t is only known somewhere in the nursery.
Here’s what it should be doing:
async with trio.open_nursery() as nursery:
run_scene(nursery) # exits when the scene finishes
nursery.cancel_scope.deadline += now() + 2
Notice how run_scene is sync: all it can do is start_soon tasks. I want to give the tasks that run_scene spawned at most 2 seconds to close, once it run_scene has exited. I can’t cancel straight away because
the async close tasks (whatever they are) have been start_soon, not awaited.
But there’s no now() function. Looking at the documentation for move_on_at, I’m not even sure that I understand how to use it.
cancel_scope.deadline: An absolute time on the current run’s clock at which this scope will automatically become cancelled.
How can we know the internal time of the clock?
I looked at the source code of move_on_after, because it has to use this now() function, and it uses _core!
Is there an other way to access the internal time? Because I should be able to use every regular function like move_on_after without using _core, right?
However, it seems to me like you should just be wrapping the async with trio.open_nursery() block in a with trio.move_on_after(2) block. Since, as you pointed out, start_soon and therefore run_scene are synchronous, run_scene should complete almost instantly, right? That should be good enough to implement your “two seconds after all tasks have spawned” deadline.
In fact you should be able to implement most regular functions like move_on_after without using _core… the reason Trio has a _core subpackage internally is to collect together the, well, core code that has to have special knowledge of Trio internals and couldn’t be implemented as a third-party library. Everything that _core exports also gets re-exported publicly (in trio, trio.hazmat, or trio.testing, depending on what it is), and everything in trio/*.py is implemented using only these public exports. So anything you see in trio/*.py is stuff that you can reimplement yourself if you wanted to, using only public APIs. The point of _core is to make sure that code like move_on_after isn’t accidentally cheating and using private APIs.
There’s definitely no way you could guess this just from looking at trio/_timeouts.py though… I opened an issue to hopefully help the next person: