2018-10-12 07:02:21 +01:00
|
|
|
import asyncio
|
|
|
|
import contextlib
|
|
|
|
|
2019-06-04 08:58:00 +01:00
|
|
|
import pytest
|
|
|
|
|
2019-04-23 22:44:42 +01:00
|
|
|
from sanic.response import stream, text
|
2018-10-12 07:02:21 +01:00
|
|
|
|
|
|
|
|
2019-06-04 08:58:00 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_request_cancel_when_connection_lost(app):
|
2021-12-23 22:30:27 +00:00
|
|
|
app.ctx.still_serving_cancelled_request = False
|
2018-10-12 07:02:21 +01:00
|
|
|
|
2018-12-30 11:18:06 +00:00
|
|
|
@app.get("/")
|
2018-10-12 07:02:21 +01:00
|
|
|
async def handler(request):
|
|
|
|
await asyncio.sleep(1.0)
|
|
|
|
# at this point client is already disconnected
|
2021-12-23 22:30:27 +00:00
|
|
|
app.ctx.still_serving_cancelled_request = True
|
2018-12-30 11:18:06 +00:00
|
|
|
return text("OK")
|
2018-10-12 07:02:21 +01:00
|
|
|
|
|
|
|
# schedule client call
|
2019-06-04 08:58:00 +01:00
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
task = loop.create_task(app.asgi_client.get("/"))
|
2018-10-12 07:02:21 +01:00
|
|
|
loop.call_later(0.01, task)
|
|
|
|
await asyncio.sleep(0.5)
|
|
|
|
|
|
|
|
# cancelling request and closing connection after 0.5 sec
|
|
|
|
task.cancel()
|
|
|
|
|
|
|
|
with contextlib.suppress(asyncio.CancelledError):
|
|
|
|
await task
|
|
|
|
|
|
|
|
# Wait for server and check if it's still serving the cancelled request
|
|
|
|
await asyncio.sleep(1.0)
|
|
|
|
|
2021-12-23 22:30:27 +00:00
|
|
|
assert app.ctx.still_serving_cancelled_request is False
|
2018-10-12 07:12:33 +01:00
|
|
|
|
|
|
|
|
2019-06-04 08:58:00 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
async def test_stream_request_cancel_when_conn_lost(app):
|
2021-12-23 22:30:27 +00:00
|
|
|
app.ctx.still_serving_cancelled_request = False
|
2018-10-12 07:12:33 +01:00
|
|
|
|
2018-12-30 11:18:06 +00:00
|
|
|
@app.post("/post/<id>", stream=True)
|
2018-10-12 07:12:33 +01:00
|
|
|
async def post(request, id):
|
|
|
|
assert isinstance(request.stream, asyncio.Queue)
|
|
|
|
|
|
|
|
async def streaming(response):
|
|
|
|
while True:
|
|
|
|
body = await request.stream.get()
|
|
|
|
if body is None:
|
|
|
|
break
|
2018-12-30 11:18:06 +00:00
|
|
|
await response.write(body.decode("utf-8"))
|
2018-10-12 07:12:33 +01:00
|
|
|
|
|
|
|
await asyncio.sleep(1.0)
|
|
|
|
# at this point client is already disconnected
|
2021-12-23 22:30:27 +00:00
|
|
|
app.ctx.still_serving_cancelled_request = True
|
2018-10-12 07:12:33 +01:00
|
|
|
|
|
|
|
return stream(streaming)
|
|
|
|
|
|
|
|
# schedule client call
|
2019-06-04 08:58:00 +01:00
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
task = loop.create_task(app.asgi_client.post("/post/1"))
|
2018-10-12 07:12:33 +01:00
|
|
|
loop.call_later(0.01, task)
|
|
|
|
await asyncio.sleep(0.5)
|
|
|
|
|
|
|
|
# cancelling request and closing connection after 0.5 sec
|
|
|
|
task.cancel()
|
|
|
|
|
|
|
|
with contextlib.suppress(asyncio.CancelledError):
|
|
|
|
await task
|
|
|
|
|
|
|
|
# Wait for server and check if it's still serving the cancelled request
|
|
|
|
await asyncio.sleep(1.0)
|
|
|
|
|
2021-12-23 22:30:27 +00:00
|
|
|
assert app.ctx.still_serving_cancelled_request is False
|