How can I learn how to implement a custom Python asyncio event loop?
python
Solution
The documentation says to inherit from `AbstractEventLoop`.
For the rest of your question, I didn't find the documentation very clear, but the source code for the concrete event loop in `asyncio` was helpful. I've written up a pretty minimal example of inheriting from `AbstractEventLoop` to create an event driven simulator.
The main things that I'd have liked to be told are
Implement `create_task`. The end-user schedules a coroutine using `asyncio.ensure_future(coro())`, but that just calls your loop's `create_task` method. It doesn't need to be anything more than `def create_task(self, coro): return asyncio.Task(coro, loop=self)`.
Implement `call_soon`, `call_at` and `call_later`. These are invoked by the end-user to schedule a plain callback function. They are also invoked by the async/await system automatically, whenever the end-user schedules a coroutine.
If a regular callback raises an exception, it goes to your loop's `call_exception_handler` method. If a coroutine raises an exception, the exception lives in some asynchronous never-never land, and you have to catch it there.
Look up the source code for `AbstractEventLoop` to see all the other methods that you should be overriding. Bonus: somewhat helpful comments.
Problem
I’m looking into implementing a new event loop to plug into `asyncio` based on existing run loop implementations, such as Cocoa’s `NSRunLoop` and Qt’s `QEventLoop`. but find it difficult to to pick a place to start. The documentation says that the system is designed to be pluggable, but nowhere does it say exactly how this can be done. Should I start with `AbstractEventLoop`, or `BaseEventLoop`? What method does what, and what components do I need to provide? The only alternative implementation I find useful is uvloop, but find it difficult to understand because it relies heavily on Cython and libuv, which I am not familiar with. Is there some kind of a write-up on how the event loop implementation is done, and how a custom one can be made? Or a less involved implementation I can wrap my head around more quickly? Thanks for any pointers.