Skip to content

Instantly share code, notes, and snippets.

@dubslow
Last active April 17, 2023 17:08
Show Gist options
  • Save dubslow/449c7743e917b6130719df7be01b8b26 to your computer and use it in GitHub Desktop.
Save dubslow/449c7743e917b6130719df7be01b8b26 to your computer and use it in GitHub Desktop.
toy example of returning async results to after-nursery sync context
import trio
from random import random
# modified and expanded from the trio docs
class Conn:
def __init__(self, text):
self.text = text
async def read(self): # not truly async ofc, but let us pretend this is dynamic
return self.text
async def handler(conn):
count = 0
#while True:
text = await conn.read()
print(f"got {text=} from new conn")
count += 1
await trio.sleep(5*random()) # read something else
count += 1
# IRL we would handle many messages over this one conn in an infinite loop.
# we don't know how many messages we've handled until the conn is closed,
# which may be no earlier than the nursery itself closing.
return count # Return async results back to sync context via nursery!
# (something something cancellation breaks this)
async def get_new_connection():
text = await trio.to_thread.run_sync(input,"awaiting next connection: ")
return Conn(text)
async def new_connection_listener(handler, nursery):
while True:
conn = await get_new_connection()
nursery.start_soon(handler, conn)
async def server(handler):
async with trio.open_nursery() as nursery:
nursery.start_soon(new_connection_listener, handler, nursery)
# exit with, now the nursery is closed.
total_messages = sum(nursery.results[handler])
total_conns = sum(nursery.results[new_connection_listener])
return total_conns, total_messages # Return async results back to sync context via nursery!
# (something something cancellation breaks this)
if __name__ == '__main__':
conns, messages = trio.run(server, handler)
print(f"After server closed, we've counted lifetime total {conns=} {messages=}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment