Event Loop

Describing the Asyncio Event Loop

  • We can think of an event loop as a while True loop
  • Specifically, this loop does the following:

    • Monitors coroutines
    • Takes feedback of idle coroutines
    • Looks for executable coroutines
  • In other words, the event loop wakes up udle coroutines when resources for that coroutine become available

Significant Properties of the Event Loop

  1. Asyncio implicitly handles the entire management of the event loop when running a coroutine:
>>> asyncio.run(coro())
  1. Coroutines don't do much until they're tied to an event loop:
>>> import asyncio

>>> async def coro():
...     print('Hello')
...     await asyncio.sleep(1)
...     print('World')

>>> coro()
<coroutine object coro>

>>> asyncio.run(coro())
'Hello'
'World'
  1. By default, an asyncio event loop runs:

    • In a single thread
    • And on a single CPU core

Motivating Events

  • A coroutine is a separate concept from threads and processes
  • It has no concept of yielding control to a new coroutine
  • Instead, it can only yield control to its caller
  • Its caller is located at the bottom of the coroutine stack
  • This calling function switches to another coroutine and runs its
  • Each coroutine is run by a single event loop
  • When a coroutine suspends:

    • The function waits until signaled to resume
    • Once the function resumes, it yields an event

How Events Interact with the Event Loop

  • The event loop waits for events to occur
  • Several coroutine await each other
  • Until, an event is awaited finally
  • This event can communicate directly with the event loop
  • It can do this by yielding control
  • Essentially, coroutine suspensions allow the event loop to directly communication with events

Illustrating Events in the Event Loop

  • The simplest event to handle is reaching a point in time
  • We can illustrate this concept using time.sleep()
  • However, the time.sleep function blocks I/O execution
  • Ideally, we should use a function that does the following:

    • Suspends until the timeout has been reached
    • Informs the event loop when the function is ready
  • Fortunately, asyncio provides us with a function that does this
  • It is called asyncio.sleep()
  • There are many other functions that are able to suspend without blocking I/O
  • However, asyncio needs to provide us with these functions

Defining Custom Events for the Event Loop

  • An event is simply a value we can identify
  • A class can be defined for this
  • Specifically, it will need to store event information
  • Implying, we must implement the special function __await__
  • Note, the class only stores the event
  • It does not say how to actually handle the event

References

Previous
Next

Call Stack

Concurrency Options