Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I learn how to implement a custom Python asyncio event loop?

Tags:

python

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.

like image 820
uranusjr Avatar asked Oct 30 '16 13:10

uranusjr


People also ask

How do I start Asyncio event loop?

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.

How does the Asyncio event loop work?

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.

How is Python Asyncio implemented?

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.


1 Answers

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.

like image 98
DamonJW Avatar answered Oct 18 '22 11:10

DamonJW