On Sun, Oct 12, 2014 at 8:04 AM, Victor Stinner <[email protected]>
wrote:

> I also added examples of UDP echo client and echo server:
>
> https://docs.python.org/dev/library/asyncio-protocol.html#udp-echo-client-protocol
>
> https://docs.python.org/dev/library/asyncio-protocol.html#udp-echo-server-protocol
>
> In the UDP echo server example, you have a more concrete example of
> "waiting until the socket is closed". The create_datagram_endpoint()
> returns a pair of (transport, protocol), whereas create_server()
> returns a Server class. The Server class has a close() method but also
> a wait_closed() method. A transport has a close() method but no
> wait_closed() method.
>
> In the UDP echo server example, tranport.close() is called while the
> event loop is not running. The transport enters the status "closing",
> but since the event loop is not run again, the socket is never closed
> and a ResourceWarning is emitted.
>

The proper solution here would be to use a Future that is made completed
when the protocol is told the connection is closed. I would add this line
to connection_made() in the server:

        self.completed = asyncio.Future()

Then add a connection_lost() method like this:

    def connection_lost(self, exc):
        if exc is None:
            self.completed.set_result(None)
        else:
            self.completed.set_exception(exc)

In your main code, after catching KeyboardInterrupt, you can then use

transport.close()
loop.run_until_complete(protocol.completed)
loop.close()

NOTE: If an error happens to the transport the loop.close() call won't
actually be reached; you can solve this in various ways, e.g. by not
calling set_exception(), or using try/finally.

-- 
--Guido van Rossum (python.org/~guido)

Reply via email to