liveBook · Manning

BaseSelector

As explained in Python Concurrency with asyncio

BaseSelector is the abstract base class defining the common interface for Python selector implementations.

BaseSelector is the abstract interface behind Python selector implementations. It hides operating-system-specific event notification so socket event loops can remain portable. section 3.4

Its event-loop model rests on three operations:

  • Register sockets with the events to monitor, such as read or write, and deregister them when monitoring is no longer needed. section 3.4
  • Call select to block until sockets are ready, optionally supplying a timeout that returns no events when it expires. section 3.4
  • Use DefaultSelector when the platform-specific implementation should be selected automatically. section 3.4
Listing 3.7 Using selectors to build a non-blocking server
import selectors
import socket
from selectors import SelectorKey
from typing import List, Tuple
 
selector = selectors.DefaultSelector()
 
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 
server_address = ('127.0.0.1', 8000)
server_socket.setblocking(False)
server_socket.bind(server_address)
server_socket.listen()
 
selector.register(server_socket, selectors.EVENT_READ)
 
while True:
    events: List[Tuple[SelectorKey, int]] = selector.select(timeout=1)  #1
 
    if len(events) == 0:                                                #2
        print('No events, waiting a bit more!')
 
    for event, _ in events:
        event_socket = event.fileobj                                    #3
 
        if event_socket == server_socket:                               #4
            connection, address = server_socket.accept()
            connection.setblocking(False)
            print(f"I got a connection from {address}")
            selector.register(connection, selectors.EVENT_READ)         #5
        else:
            data = event_socket.recv(1024)                              #6
            print(f"I got some data: {data}")
            event_socket.send(data)

A non-blocking echo server demonstrates registering the listening socket, handling client connections, waiting for readable sockets, and returning received data. section 3.4

How Python Concurrency with asyncio covers it

How deep it goes
Defines registration, deregistration, blocking select, timeouts, and implementations, then applies them in an echo server.
Examples
Uses a non-blocking echo server that monitors a listening socket and client data.
What you can do after
Operate a socket event loop by registering sockets, waiting for readiness, processing events, and applying timeouts.
How it connects
Connects selectors to sockets, asyncio concurrency, event loops, non-blocking servers, and DefaultSelector.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Concurrency with asyncio. The section links point to the parts of the book it draws on.