Is there a way to manually exit a trio infinite loop, like the echo client in the trio tutorial, https://trio.readthedocs.io/en/latest/tutorial.html#an-echo-client , other than using Ctrl-C
or using timeouts?
My idea is to use call the echo client from another python script, and be able to close it too with the same python script, arbitrarily. I was thinking of using a flag (maybe event?) as a switch to trigger the cancel_scope.cancel()
in the nursery. But I don't know how to trigger the switch. Below is my attempt at modifying the tutorial echo client code.
import sys
import trio
PORT = 12345
BUFSIZE = 16384
FLAG = 1 # FLAG is a global variable
async def sender(client_stream):
print("sender: started")
while FLAG:
data = b'async can sometimes be confusing but I believe in you!'
print(f"sender: sending {data}")
await client_stream.send_all(data)
await trio.sleep(1)
async def receiver(client_stream):
print("recevier: started!")
while FLAG:
data = await client_stream.receive_some(BUFSIZE)
print(f"receiver: got data {data}")
if not data:
print("receiver: connection closed")
sys.exit()
async def checkflag(nursery): # function to trigger cancel()
global FLAG
if not FLAG:
nursery.cancel_scope.cancel()
else:
# keep this task running if not triggered, but how to trigger it,
# without Ctrl-C or timeout?
await trio.sleep(1)
async def parent():
print(f"parent: connecting to 127.0.0.1:{PORT}")
client_stream = await trio.open_tcp_stream("127.0.0.1", PORT)
async with client_stream:
async with trio.open_nursery() as nursery:
print("parent: spawning sender ...")
nursery.start_soon(sender, client_stream)
print("parent: spawning receiver ...")
nursery.start_soon(receiver, client_stream)
print("parent: spawning checkflag...")
nursery.start_soon(checkflag, nursery)
print('Close nursery...')
print("Close stream...")
trio.run(parent)
I find that I am unable to input any commands into the python REPL after trio.run()
, to manually change the FLAG
, and am wondering if I call this echo client from another script, how exactly to trigger the cancel_scope.cancel()
in the nursery? Or is there a better way? Really appreciate all help. Thanks.