I have never really given much thought about the behaviour for passing a coroutine to gather() directly. At some point I added await coro() directly as a useful shorthand for await taskMgr.add(coro()), but I suppose that gather() should apply the same logic.
Thinking about it, I would say yes, tit would be useful to be in 1.10.9. If people like me simply apply what they have learned using asyncio, the change of behaviour would be unexpected.
Otherwise the documentation should perhaps describe the discrepencies between asyncio and panda3d ?
Hmm, one sticky point is that there’s no obvious way for Panda to know which task manager and task chain to schedule the task on. We could just pick “the default one” for both, which is apparently what asyncio does, and may be sufficient for most use cases, though I find it mildly inelegant.
Alternatively, we could deviate from asyncio here, and instead of scheduling the task in gather, do it in await; it would loop over the futures in a gathering future and make sure all of them are scheduled with whatever task manager is managing the task that you’re awaiting it from.
Do you have any thoughts? I’m almost wondering whether perhaps gather() should be a method on the task manager to make this less ambiguous.
The implementation of gather() in asyncio schedules the tasks either on the current loop, or, if there is no loop, on the default loop. If I translate this into Panda parlance, Task.gather() should schedule the task using the current taskChain, or the default taskChain if gather() is called from outside. Is my understanding correct ?
If gather can not find or use the current task chain, using the default one feels a bit dangerous. In my app, I have a couple of taskChain running, some of them in asynchronous threads, so I don’t want gather to implicitly trigger a thread switch.
Perhaps your suggestion of doing the scheduling in await instead of gather is the most fool proof solution.
But again, I’m only a vanilla user of asyncio (and now “async-panda”) so I’m maybe missing what are the practical impacts of each solution?
It now schedules the coroutine with the currently running task’s chain and manager. If not called within a task, prints a warning—I figure it’s easy enough for a user to explicitly convert it into a task using taskMgr.add if they need to use it from outside a task.