Skip to content

Commit

Permalink
Add forgotten files
Browse files Browse the repository at this point in the history
  • Loading branch information
njsmith committed Oct 5, 2018
1 parent 9600a1c commit 177bc0c
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
44 changes: 44 additions & 0 deletions docs/source/reference-core/blocking-trio-portal-example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import trio
import threading

def thread_fn(portal, receive_from_trio, send_to_trio):
while True:
# Since we're in a thread, we can't call methods on Trio
# objects directly -- so we use our portal to call them.
try:
request = portal.run(receive_from_trio.receive)
except trio.EndOfChannel:
portal.run(send_to_trio.aclose)
return
else:
response = request + 1
portal.run(send_to_trio.send, response)

async def main():
portal = trio.BlockingTrioPortal()
send_to_thread, receive_from_trio = trio.open_memory_channel(0)
send_to_trio, receive_from_thread = trio.open_memory_channel(0)

async with trio.open_nursery() as nursery:
# In a background thread, run:
# thread_fn(portal, receive_from_trio, send_to_trio)
nursery.start_soon(
trio.run_sync_in_worker_thread,
thread_fn, portal, receive_from_trio, send_to_trio
)

# prints "1"
await send_to_thread.send(0)
print(await receive_from_thread.receive())

# prints "2"
await send_to_thread.send(1)
print(await receive_from_thread.receive())

# When we close the channel, it signals the thread to exit.
await send_to_thread.aclose()

# When we exit the nursery, it waits for the background thread to
# exit.

trio.run(main)
30 changes: 30 additions & 0 deletions docs/source/reference-core/channels-mpmc-broken.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This example usually crashes!

import trio
import random

async def main():
async with trio.open_nursery() as nursery:
send_channel, receive_channel = trio.open_memory_channel(0)
# Start two producers
nursery.start_soon(producer, "A", send_channel)
nursery.start_soon(producer, "B", send_channel)
# And two consumers
nursery.start_soon(consumer, "X", receive_channel)
nursery.start_soon(consumer, "Y", receive_channel)

async def producer(name, send_channel):
async with send_channel:
for i in range(3):
await send_channel.send("{} from producer {}".format(i, name))
# Random sleeps help trigger the problem more reliably
await trio.sleep(random.random())

async def consumer(name, receive_channel):
async with receive_channel:
async for value in receive_channel:
print("consumer {} got value {!r}".format(name, value))
# Random sleeps help trigger the problem more reliably
await trio.sleep(random.random())

trio.run(main)
29 changes: 29 additions & 0 deletions docs/source/reference-core/channels-mpmc-fixed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import trio
import random

async def main():
async with trio.open_nursery() as nursery:
send_channel, receive_channel = trio.open_memory_channel(0)
async with send_channel, receive_channel:
# Start two producers, giving each its own private clone
nursery.start_soon(producer, "A", send_channel.clone())
nursery.start_soon(producer, "B", send_channel.clone())
# And two consumers, giving each its own private clone
nursery.start_soon(consumer, "X", receive_channel.clone())
nursery.start_soon(consumer, "Y", receive_channel.clone())

async def producer(name, send_channel):
async with send_channel:
for i in range(3):
await send_channel.send("{} from producer {}".format(i, name))
# Random sleeps help trigger the problem more reliably
await trio.sleep(random.random())

async def consumer(name, receive_channel):
async with receive_channel:
async for value in receive_channel:
print("consumer {} got value {!r}".format(name, value))
# Random sleeps help trigger the problem more reliably
await trio.sleep(random.random())

trio.run(main)

0 comments on commit 177bc0c

Please sign in to comment.