Skip to content

Commit

Permalink
Make error reproducible by emulating 0.15.0 logic
Browse files Browse the repository at this point in the history
`RuntimeError: No response returned.`
  • Loading branch information
acjh committed Jun 25, 2022
1 parent ea19904 commit 37dd8ac
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
15 changes: 13 additions & 2 deletions starlette/concurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,21 @@


async def run_until_first_complete(*args: typing.Tuple[typing.Callable, dict]) -> None:
tasks = [create_task(handler(**kwargs)) for handler, kwargs in args]
async def run(func: typing.Callable[[], typing.Coroutine]) -> None:
await func()
# (starlette 0.15.0) starlette.concurrency.run_until_first_complete `task_group.cancel_scope.cancel()`
for task in tasks:
if not task.done() and task != asyncio.current_task():
task.cancel()

tasks = [create_task(run(functools.partial(handler, **kwargs))) for handler, kwargs in args]
(done, pending) = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
[task.cancel() for task in pending]
[task.result() for task in done]
for task in done:
try:
task.result()
except asyncio.CancelledError:
pass


async def run_in_threadpool(
Expand Down
5 changes: 4 additions & 1 deletion starlette/middleware/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ async def call_next(self, request: Request) -> Response:

scope = request.scope
receive = request.receive
send = queue.put

async def send(item: typing.Any) -> None:
await asyncio.sleep(0) # anyio.streams.memory.MemoryObjectSendStream.send `await checkpoint()`
await queue.put(item)

async def coro() -> None:
try:
Expand Down

0 comments on commit 37dd8ac

Please sign in to comment.