Wenn Sie einen Webserver mit aiohttp erstellen und beim Empfang einer HTTP-Anforderung [^ job] einen etwas schweren Prozess ausführen möchten, wird die HTTP-Antwort nur langsam zurückgegeben, und es tritt ein Timeout-Fehler auf der Clientseite auf Es kann verarbeitet werden. Was ist, wenn Sie das Verarbeitungsergebnis nicht zurückgeben müssen und eine HTTP-Antwort zurückgeben, die HTTP-Kommunikation beenden und dann einen etwas schwereren Prozess ausführen möchten?
** Ich fand diese Methode nicht gut, siehe das Postscript. ** ** **
from asyncio import sleep
from aiohttp import web
async def handler(request):
response = web.Response()
await response.prepare(request)
await response.write_eof()
await sleep(1) #Verarbeitung nach Rückgabe einer Antwort
app = web.Application()
app.router.add_get('/', handler)
if __name__ == '__main__':
web.run_app(app)
Wenn beim Erstellen des Antwortobjekts nichts angegeben wird, lautet der HTTP-Statuscode 200.
Wenn bei der obigen Methode die Verbindung mit Keep-Alive für einen bestimmten Zeitraum aufrechterhalten wird, funktioniert sie ohne Probleme, sodass ich sie nicht bemerkt habe, aber im Grunde funktioniert sie nicht gut.
Wenn Sie versuchen, Keep-Alive zu deaktivieren, indem Sie "Connection: close" zum Antwortheader hinzufügen, können Sie feststellen, dass die nachfolgende asynchrone Verarbeitung zum Zeitpunkt von "write_eof ()" nicht ausgeführt wird.
Wenn die Verbindung zum Client unterbrochen wird, wird anscheinend die Verarbeitung des Anforderungshandlers dort gestoppt. (Es war schwer herauszufinden, da es keine Fehlermeldung gab)
Referenz: https://github.com/aio-libs/aiohttp/issues/4773
Als Lösung scheint es besser zu sein, aiojobs zu verwenden.
from asyncio import sleep
from aiohttp import web
import aiojobs.aiohttp as aiojobs
async def job():
"""Der Prozess, den Sie ausführen möchten, nachdem Sie eine Antwort zurückgegeben haben"""
await sleep(1)
async def handler(request):
await aiojobs.spawn(request, job())
return web.Response(text='ok')
app = web.Application()
app.router.add_get('/', handler)
aiojobs.setup(app)
if __name__ == '__main__':
web.run_app(app)