2017-11-08 14 views
1

ich derzeit aiohttp teste am Umgang mit und ich habe ein Problem mit dem folgenden Code aufweisen:vorzeitige Client Trennung in aiohttp

async def index(request: web.Request) -> web.StreamResponse: 
    response = web.StreamResponse(headers={'content-type': 'text/plain'}) 
    await response.prepare(request) 
    for i in range(1000000): 
     try: 
      response.write(b'test response') 
      await response.drain() 
     except concurrent.futures.CancelledError: 
      print('Remote connection closed... Cleaning up...') 
      # Do cleanup process here? 
      raise 

    return response 

Jetzt versuche ich dies mit der folgenden curl Anfrage aus:

curl -v http://127.0.0.1:8080 

Und dann drücke ich Ctrl-C, um die Verbindung zu lösen und das Herunterladen der Antwort zu stoppen.

Auf dem Konsolenprotokoll aus dem aiohttp Web-Server erhalte ich viel der folgenden Möglichkeiten:

2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception. 
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception. 
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception. 
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception. 
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception. 

Welche Looping hält und ich kann den Server mit Strg-C nicht töten. Ich muss es mit kill -KILL töten, um es vollständig zu beenden. Es scheint, dass die Client-Socket-Verbindung stillschweigend behandelt wird. Ich möchte die obigen Warnungen, die von asyncio.selector_events._SelectorSocketTransport.write() geworfen werden, zum Schweigen bringen. Ich könnte das zum Schweigen bringen, indem ich das entsprechende Logger-Level einstelle, aber das ist nicht das, was ich will. Außerdem gibt es viele Aufräumvorgänge, die ich ausführen möchte, wenn eine Clientverbindung beendet wird. Ich habe den aiohttp-Code durchgesehen und es scheint keine Handler oder Signale zu geben, an die ich mich anhängen könnte. Idealerweise möchte ich in der Lage sein, etwas zu bereinigen, wenn eine Client-Verbindung geschlossen wird.

In Django kann ich es tun, indem Sie eine benutzerdefinierte SelfCleaningStream Klasse mit der StreamingHttpResponse Klasse erstellen. Die benutzerdefinierte Klasse SelfCleaningStream behandelt die Bereinigung in der Methode close(), die von Django aufgerufen wird, wenn eine Clientverbindung geschlossen wird.

+0

Nicht sicher, ob es endgültige Antwort ist, aber Sie sollten auf jeden Fall verwenden 'asyncio.CancelledError' statt' concurrent.futures.CancelledError' - diese verschiedenen Klassen sind. –

+0

Eigentlich habe ich es mit beiden Ausnahmen in einem Tupel versucht. Keines wird geworfen, und es scheint, dass dies ein Fehler in aiohttp ist. In der Zwischenzeit habe ich daran gearbeitet, indem ich 'request.protocol.transport.is_closing()' vor 'response.write()' überprüft habe. –

Antwort

1

Danke für den Bericht. Es ist ein Fehler in aiohttp habe ich eingereicht ein issue