如何安全关闭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区分本地关闭和远程关闭。如果连接被远程端关闭,则关闭它仍然可以。 (正是出于这个原因)

(如果它在本地具有aclose(),则再次将其关闭也可以。在任何一种情况下,它都是noop(执行检查点除外)。)

如果在关闭连接后使用连接,则会得到ClosedResourceError(这是您应解决的编程错误),而在连接出现问题后使用连接,则得到BrokenResourceError另一面(有时由于网络多变,这应该可以预期。)