Fix the blocking call scan for async handlers
Your task
An AI wrote a FastAPI quote endpoint as async def and called requests.get inside it. That call blocks, and an async def handler runs on the event loop, the one thread that runs every coroutine. Under load, every endpoint in the service stalled behind it. Your team now scans the route table for async handlers that call a blocking library.
An assistant wrote find_blocking_async_handlers(handlers). It is in the editor. It has a bug. Find it and fix it.
Input and output:
handlers: one record per route handler, in the form"name|kind|calls", like"get_quote|async|requests.get,resp.json". The kind is normallyasync(declaredasync def) orsync(a plaindef, which FastAPI runs in a thread pool). The calls are a comma separated list of what the handler calls, possibly empty.handlersitself can be empty.- Return the names of the handlers that block the event loop.
Rules the tests check:
- Split each record on
|. Skip a record that does not have exactly 3 parts. - Trim whitespace at both ends of the name, the kind and the calls. Skip a record whose name is empty after trimming.
- Only async handlers count. The kind compares without case, so
ASYNCis async. Skip every other kind. - Split the calls on
,and trim each call. Ignore empty calls. - A call blocks when it is exactly
time.sleepor exactlyopen, or when it starts withrequests.,urllib.,psycopg2.orsocket., the dot included. Calls compare with case. No other call blocks. - Report a handler once when at least one of its calls blocks.
- Return the names in input order. A name on two flagged records appears twice.
Examples
find_blocking_async_handlers(handlers: list[str]) -> list[str]Example 1
Input
find_blocking_async_handlers(["get_quote|async|requests.get,resp.json", "healthz|async|", "list_items|sync|requests.post"])Output
["get_quote"]Example 2
Input
find_blocking_async_handlers(["get_quote|async|httpx.AsyncClient.get,resp.json", "sleeper|async|time.sleep,log.info"])Output
["sleeper"]Example 3
Input
find_blocking_async_handlers(["a|async|requests.get", "b|async|urllib.request.urlopen", "c|async|psycopg2.connect", "d|async|socket.recv"])Output
["a", "b", "c", "d"]