如何安全地关闭 Trio 中的连接?
How to safely close a connection in Trio?
我有一个连接的应用程序逻辑全部包裹在一个大 try/except/finally 块中:
async def serve(self, stream: trio.SocketStream):
try:
async with trio.open_nursery() as nursery:
pass # code goes here to do some reading and writing
except Exception as e:
print("Got exception:", e)
except trio.Cancelled:
print("Cancelled")
raise
# some other handlers, mostly just logging
finally:
# ... some other stuff ...
# ... then shut the connection:
with trio.move_on_after(1):
await stream.aclose()
我不清楚是否应该尝试在 finally 子句中关闭连接。如果异常是由于应用程序错误(来自连接的无效消息或协程被取消)引起的,这似乎是正确的做法,但如果异常是连接从另一端关闭,那么这似乎适得其反 - 我期望旧异常会被新异常掩盖。有什么想法吗?我也许可以将它包装在自己的 try/except 中并忽略任何异常。
On the python-trio/general Gitter chat,Joshua Oreman @oremanj 友善地提供了这个答案:
Trio distinguishes between local and remote close. If a connection got closed by the remote side, it's still fine to aclose() it. (Precisely for this reason)
(If it got aclose()'d locally, it's also fine to aclose() it again. It's a noop (except for executing a checkpoint) in either case.)
You get ClosedResourceError
if you use the connection after you closed it (this is a programming error that you should fix), as opposed to BrokenResourceError
if you use the connection after some problem occurred on the other side (this should be expected sometimes due to the vagaries of networks).
我有一个连接的应用程序逻辑全部包裹在一个大 try/except/finally 块中:
async def serve(self, stream: trio.SocketStream):
try:
async with trio.open_nursery() as nursery:
pass # code goes here to do some reading and writing
except Exception as e:
print("Got exception:", e)
except trio.Cancelled:
print("Cancelled")
raise
# some other handlers, mostly just logging
finally:
# ... some other stuff ...
# ... then shut the connection:
with trio.move_on_after(1):
await stream.aclose()
我不清楚是否应该尝试在 finally 子句中关闭连接。如果异常是由于应用程序错误(来自连接的无效消息或协程被取消)引起的,这似乎是正确的做法,但如果异常是连接从另一端关闭,那么这似乎适得其反 - 我期望旧异常会被新异常掩盖。有什么想法吗?我也许可以将它包装在自己的 try/except 中并忽略任何异常。
On the python-trio/general Gitter chat,Joshua Oreman @oremanj 友善地提供了这个答案:
Trio distinguishes between local and remote close. If a connection got closed by the remote side, it's still fine to aclose() it. (Precisely for this reason)
(If it got aclose()'d locally, it's also fine to aclose() it again. It's a noop (except for executing a checkpoint) in either case.)
You get
ClosedResourceError
if you use the connection after you closed it (this is a programming error that you should fix), as opposed toBrokenResourceError
if you use the connection after some problem occurred on the other side (this should be expected sometimes due to the vagaries of networks).