Experiment: Wrap all capnp code in a context-manager to avoid segfaults (#317)
* Experiment: Wrap all capnp code in a context-manager * Fix segfault in on_disconnect
This commit is contained in:
committed by
GitHub
parent
d48ffea939
commit
e13a0c9254
@@ -306,4 +306,4 @@ async def cmd_main(host):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(cmd_main(parse_args().host))
|
||||
asyncio.run(capnp.run(cmd_main(parse_args().host)))
|
||||
|
||||
@@ -131,4 +131,4 @@ async def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
asyncio.run(capnp.run(main()))
|
||||
|
||||
@@ -24,11 +24,6 @@ class StatusSubscriber(thread_capnp.Example.StatusSubscriber.Server):
|
||||
print("status: {}".format(time.time()))
|
||||
|
||||
|
||||
async def background(cap):
|
||||
subscriber = StatusSubscriber()
|
||||
await cap.subscribeStatus(subscriber)
|
||||
|
||||
|
||||
async def main(host):
|
||||
host, port = host.split(":")
|
||||
connection = await capnp.AsyncIoStream.create_connection(host=host, port=port)
|
||||
@@ -36,7 +31,7 @@ async def main(host):
|
||||
cap = client.bootstrap().cast_as(thread_capnp.Example)
|
||||
|
||||
# Start background task for subscriber
|
||||
asyncio.create_task(background(cap))
|
||||
task = asyncio.ensure_future(cap.subscribeStatus(StatusSubscriber()))
|
||||
|
||||
# Run blocking tasks
|
||||
print("main: {}".format(time.time()))
|
||||
@@ -47,12 +42,14 @@ async def main(host):
|
||||
await cap.longRunning()
|
||||
print("main: {}".format(time.time()))
|
||||
|
||||
task.cancel()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
asyncio.run(main(args.host))
|
||||
asyncio.run(capnp.run(main(args.host)))
|
||||
|
||||
# Test that we can run multiple asyncio loops in sequence. This is particularly tricky, because
|
||||
# main contains a background task that we never cancel. The entire loop gets cleaned up anyways,
|
||||
# and we can start a new loop.
|
||||
asyncio.run(main(args.host))
|
||||
asyncio.run(capnp.run(main(args.host)))
|
||||
|
||||
@@ -41,11 +41,6 @@ async def watch_connection(cap):
|
||||
return False
|
||||
|
||||
|
||||
async def background(cap):
|
||||
subscriber = StatusSubscriber()
|
||||
await cap.subscribeStatus(subscriber)
|
||||
|
||||
|
||||
async def main(host):
|
||||
addr, port = host.split(":")
|
||||
|
||||
@@ -71,7 +66,9 @@ async def main(host):
|
||||
|
||||
# Start watcher to restart socket connection if it is lost and subscriber background task
|
||||
background_tasks = asyncio.gather(
|
||||
background(cap), watch_connection(cap), return_exceptions=True
|
||||
cap.subscribeStatus(StatusSubscriber()),
|
||||
watch_connection(cap),
|
||||
return_exceptions=True,
|
||||
)
|
||||
|
||||
# Run blocking tasks
|
||||
@@ -96,7 +93,7 @@ if __name__ == "__main__":
|
||||
while retry:
|
||||
loop = asyncio.new_event_loop()
|
||||
try:
|
||||
retry = not loop.run_until_complete(main(parse_args().host))
|
||||
retry = not loop.run_until_complete(capnp.run(main(parse_args().host)))
|
||||
except RuntimeError:
|
||||
# If an IO is hung, the event loop will be stopped
|
||||
# and will throw RuntimeError exception
|
||||
|
||||
@@ -46,4 +46,4 @@ async def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
asyncio.run(capnp.run(main()))
|
||||
|
||||
@@ -50,4 +50,4 @@ async def main(host):
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
asyncio.run(main(args.host))
|
||||
asyncio.run(capnp.run(main(args.host)))
|
||||
|
||||
@@ -59,4 +59,4 @@ async def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
asyncio.run(capnp.run(main()))
|
||||
|
||||
@@ -330,4 +330,4 @@ if __name__ == "__main__":
|
||||
# https://bugs.python.org/issue36709
|
||||
# asyncio.run(main(parse_args().host), loop=loop, debug=True)
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(main(parse_args().host))
|
||||
loop.run_until_complete(capnp.run(main(parse_args().host)))
|
||||
|
||||
@@ -155,4 +155,4 @@ async def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
asyncio.run(capnp.run(main()))
|
||||
|
||||
@@ -15,8 +15,7 @@ this_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
usage="Connects to the Example thread server \
|
||||
at the given address and does some RPCs"
|
||||
usage="Connects to the Example thread server at the given address and does some RPCs"
|
||||
)
|
||||
parser.add_argument("host", help="HOST:PORT")
|
||||
|
||||
@@ -26,15 +25,10 @@ at the given address and does some RPCs"
|
||||
class StatusSubscriber(thread_capnp.Example.StatusSubscriber.Server):
|
||||
"""An implementation of the StatusSubscriber interface"""
|
||||
|
||||
def status(self, value, **kwargs):
|
||||
async def status(self, value, **kwargs):
|
||||
print("status: {}".format(time.time()))
|
||||
|
||||
|
||||
async def background(cap):
|
||||
subscriber = StatusSubscriber()
|
||||
await cap.subscribeStatus(subscriber)
|
||||
|
||||
|
||||
async def main(host):
|
||||
addr, port = host.split(":")
|
||||
|
||||
@@ -59,7 +53,7 @@ async def main(host):
|
||||
cap = client.bootstrap().cast_as(thread_capnp.Example)
|
||||
|
||||
# Start background task for subscriber
|
||||
asyncio.create_task(background(cap))
|
||||
task = asyncio.ensure_future(cap.subscribeStatus(StatusSubscriber()))
|
||||
|
||||
# Run blocking tasks
|
||||
print("main: {}".format(time.time()))
|
||||
@@ -70,10 +64,12 @@ async def main(host):
|
||||
await cap.longRunning()
|
||||
print("main: {}".format(time.time()))
|
||||
|
||||
task.cancel()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Using asyncio.run hits an asyncio ssl bug
|
||||
# https://bugs.python.org/issue36709
|
||||
# asyncio.run(main(parse_args().host), loop=loop, debug=True)
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(main(parse_args().host))
|
||||
loop.run_until_complete(capnp.run(main(parse_args().host)))
|
||||
|
||||
@@ -71,4 +71,4 @@ async def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
asyncio.run(capnp.run(main()))
|
||||
|
||||
Reference in New Issue
Block a user