liveBook · Manning

Selector registration

As explained in Python Concurrency with asyncio

Selector registration is the operation of associating a resource with a selector and specifying the events to monitor for it.

Selector registration associates a resource, such as a socket, with a selector and identifies the events to monitor. Read and write events let an event loop wait for activity instead of repeatedly checking every socket. section 3.4

Registration works with two related selector operations:

  • Register a server socket for read events so incoming client connections become notifications. section 3.4
  • Register each accepted client socket for read events so incoming data can be processed. section 3.4
  • Deregister sockets when they are no longer of interest; call select to wait for registered activity, optionally with a timeout. section 3.4

Non-blocking echo server

A server creates a non-blocking socket, registers it with DefaultSelector for EVENT_READ, and waits with select(timeout=1). When a client connects, the new connection is registered for data notifications; received data is written back to that client. 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)

Inspect the complete selector loop, including registration, event waiting, connection handling, and client processing. section 3.4

How Python Concurrency with asyncio covers it

How deep it goes
Explains registration, deregistration, select, timeouts, and a complete echo-server flow, but not selector implementation internals.
Examples
Demonstrates registration through a non-blocking echo server that watches a listening socket and client connections.
What you can do after
Build a non-blocking echo server using Python's selectors module and event-driven socket notifications.
How it connects
Connects selector registration with sockets, event loops, non-blocking I/O, select, and asyncio concurrency.

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.