Got it.
So, it somewhat depends what kind of handler you have.
As you may know, Sanic allows your handler to be either a regular function:
def my_request(request):
...
or async:
async def my_request(request):
...
If your view function is async
, then you really do not need to do anything. The Task will be cancelled for you. If it is a regular function, then (unfortunately), it still will continue to execute because it does not know that the connection was closed.
To illustrate this, run the following in a terminal. In a second, try to curl
the /async
and the /sync
endpoints. Before they return, hit Ctrl+C
to stop the request. You should see that the /async
will just stop. That is because the task has been cancelled. If you spawned a new task from inside there your request, it will not be stopped. In the /sync
example, it will continue to run until completion.
import asyncio
import time
from sanic import Sanic, response
app = Sanic()
@app.get("/async")
async def do_slowly_async(request):
print("Ready to sleep")
for _ in range(5):
print("\t ZZzzz...")
await asyncio.sleep(1)
print("Done sleeping")
return response.json({"yawn": True})
@app.get("/sync")
def do_slowly_sync(request):
print("Ready to sleep")
for _ in range(5):
print("\t ZZzzz...")
time.sleep(1)
print("Done sleeping")
return response.json({"yawn": True})
app.run(debug=True)
With that said, it does give me some thought that perhaps the Sanic server could provide a hook, or at least the option of a hook to provide a way to do some sort of cleanup in those cases.
Let me know if this helps.