Paul Moore wrote:
It would probably be helpful to have a concrete example of a basic event loop that did *nothing* but schedule tasks. No IO waiting or similar, just scheduling.
Take a look at the example I developed when working on the yield-from pep:
The first version of the event loop presented there does exactly that, just schedules tasks in a round- robin fashion. Then I gradually add more features to it.
Actually, what *is* the minimal event loop interface that is needed for the various task/future mechanisms to work, independently of asyncio?
I don't it's possible to answer that question, because there isn't a single answer. The minimal set of features that an event loop needs depends on what you want to achieve with it.
Even the notion of "just schedules tasks" is ambiguous. What does "schedule" mean? Does it just mean round-robin switching between them, or should they be able to synchronise with each other in some way? Should it be possible for a task to suspend itself for an interval of real world time, or does that come under the heading of I/O (since you're waiting for an external event, i.e. the computer's clock reaching some time)? Etc.
And what features of an event loop etc are needed for the PEP, if it's being used outside of asyncio?)
I don't think *any* particular event loop features are needed.
You can't pick out any of these features as being "core". For example, it would be possible to have an event loop that handled socket I/O but *didn't* do round-robin scheduling -- it could just keep on running the same task, even if it yielded, until it blocked waiting for an external event. Such a scheduler would probably be quite adequate for many use cases.
It seems to me that the idea of "generator-based tasks managed by an event loop" is more of a design pattern than something you can write a detailed API specification for.
Another problem with the "core" idea is that you can't start with an event loop that "just does scheduling" and then add on other features such as I/O *from the outside*. There has to be some point at which everything comes together, which means choosing something like select() or poll() or I/O completion queues, and build that into the heart of your event loop. At that point it's no longer something with a simple core.