Asyncio cleanups (#236)

This commit is contained in:
Tom Christie 2018-11-23 11:11:16 +00:00 committed by GitHub
parent 80369c1b85
commit ed16b7df21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 9 deletions

View File

@ -81,14 +81,19 @@ class WSGIResponder:
body += message.get("body", b"")
more_body = message.get("more_body", False)
environ = build_environ(self.scope, body)
wsgi = run_in_threadpool(self.wsgi, environ, self.start_response)
sender = self.loop.create_task(self.sender(send))
await asyncio.wait_for(wsgi, None)
self.send_queue.append(None)
self.send_event.set()
await asyncio.wait_for(sender, None)
if self.exc_info is not None:
raise self.exc_info[0].with_traceback(self.exc_info[1], self.exc_info[2])
try:
sender = self.loop.create_task(self.sender(send))
await run_in_threadpool(self.wsgi, environ, self.start_response)
self.send_queue.append(None)
self.send_event.set()
await asyncio.wait_for(sender, None)
if self.exc_info is not None:
raise self.exc_info[0].with_traceback(
self.exc_info[1], self.exc_info[2]
)
finally:
if not sender.done():
sender.cancel() # pragma: no cover
async def sender(self, send: Send) -> None:
while True:

View File

@ -181,7 +181,11 @@ class _ASGIAdapter(requests.adapters.HTTPAdapter):
response_complete = False
raw_kwargs = {"body": io.BytesIO()} # type: typing.Dict[str, typing.Any]
loop = asyncio.get_event_loop()
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
connection = self.app(scope)

32
tests/test_testclient.py Normal file
View File

@ -0,0 +1,32 @@
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.testclient import TestClient
mock_service = Starlette()
@mock_service.route("/")
def mock_service_endpoint(request):
return JSONResponse({"mock": "example"})
app = Starlette()
@app.route("/")
def homepage(request):
client = TestClient(mock_service)
response = client.get("/")
return JSONResponse(response.json())
def test_use_testclient_in_endpoint():
"""
We should be able to use the test client within applications.
This is useful if we need to mock out other services,
during tests or in development.
"""
client = TestClient(app)
response = client.get("/")
assert response.json() == {"mock": "example"}