Skip to content

Instantly share code, notes, and snippets.

@gwerbin
Last active August 8, 2020 19:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gwerbin/132f9e31ead16268b673c4d9d3883091 to your computer and use it in GitHub Desktop.
Save gwerbin/132f9e31ead16268b673c4d9d3883091 to your computer and use it in GitHub Desktop.
My attempt to understand Sans I/O style.

My attempt to understand Sans IO

The basic machinery is:

  1. An Event type
  2. A Client that receives "inbound events" (responses from previous i/o) and emits "outbound events"; one core implementation
  3. An IOClient that performs i/o based on outbound events and forms inbound events from i/o results; one implementation per i/o framework

Hypothetical implementations

Event:

class InboundEvent:
    pass

class OutboundEvent:
    pass

class SubmitRequest(OutboundEvent):
    pass

class SubmitResponse(InboundEvent):
    pass

Client:

class Record:
    ...

class Client:
    def submit(self, data: Iterable[Record]) -> Iterable[OutboundEvent]:
        """ Generate initial events from input data """
        ...

    def handle(self, event: InboundEvent) -> Iterable[OutboundEvent]:
        """ Handle inbound events, return corresponding outbound events """
        ...

IOClient:

class IOClient:
    def send(self, event: OutboundEvent) -> Iterable[InboundEvent]:
        """ Perform i/o specified by an outbound event """
        ...

class AsyncIOClient:
    async def asend(self, event: OutboundEvent) -> AsyncIterable[InboundEvent]:
       """ Perform async i/o specified by an outbound event """
       ...

Hypothetical usage example

This would be for some kind of very-minimal non-async IO client, using a very basic system for queuing events.

from queue import Queue

from clientlib import Client
from clientlib.requests import IOClient

client = Client(key='hello')
io_client = IOClient()

input_data = [
    (1, 2),
    (3, 4),
]

event_queue = Queue()

for event in client.submit(input_data):
    event_queue.push(event)

while True:
    event0 = event_queue.pop()
    response = io_client.send(event0)
    for event in client.handle(response)
        event_queue.push(event)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment