liveBook · Manning

CustomFuture

As explained in Python Concurrency with asyncio

CustomFuture is a book-local future class that can be subclassed to associate asynchronous completion with a coroutine.

CustomFuture is a minimal future implementation for asynchronous code. It stores a result, tracks completion, supports completion callbacks, and becomes awaitable through __await__. An incomplete future yields itself so an event loop can check it again; a completed future returns its result. section 14.5.3

Its core operations connect deferred results to coroutine execution:

  • set_result stores the value, marks the future finished, and invokes the registered callback. section 14.5.3
  • awaiting an incomplete future yields control; awaiting a completed future returns the stored value. section 14.5.3
  • A selector can call set_result when a socket event occurs, allowing a coroutine to await incoming connections or data. section 14.5.4
  • A task can subclass CustomFuture, wrap a coroutine, and advance it one step whenever a yielded future completes. section 14.5.5

Waiting for a socket connection

Create a CustomFuture, register its set_result method for a server socket's read event, and await the future. The coroutine pauses until a client connects; the selector callback supplies the connection and completes the future. section 14.5.4

Listing 14.8 A custom future implementation
class CustomFuture:
 
    def __init__(self):
        self._result = None
        self._is_finished = False
        self._done_callback = None
 
    def result(self):
        return self._result
 
    def is_finished(self):
        return self._is_finished
 
    def set_result(self, result):
        self._result = result
        self._is_finished = True
        if self._done_callback:
            self._done_callback(result)
 
    def add_done_callback(self, fn):
        self._done_callback = fn
 
    def __await__(self):
        if not self._is_finished:
            yield self
        return self.result()

Inspect the compact implementation of result storage, completion tracking, callbacks, and __await__. section 14.5.3

How Python Concurrency with asyncio covers it

How deep it goes
Explains __await__, callbacks, socket integration, task inheritance, and event-loop scheduling, stopping at a minimal implementation.
Examples
Demonstrates repeated future polling, socket connection acceptance, coroutine-wrapping tasks, and a minimal event loop.
What it assumes
Assumes familiarity with coroutines, generators, callbacks, selectors, and non-blocking sockets.
What you can do after
Build it from scratch, then integrate it with selectors, socket coroutines, tasks, and a minimal event loop.
How it connects
Connects awaitables, coroutines, tasks, event loops, selectors, and sockets.

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.