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.
The alternative way of starting up your event loop is to call the run_forever() method which will subsequently start your asyncio based event loop and have it run indefinitely until the program comes to an end or the stop() method is called.
The event loop is the core of every asyncio application. Event loops run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses. Application developers should typically use the high-level asyncio functions, such as asyncio.
asyncio is a library to write concurrent code using the async/await syntax. asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With