Skip to content

Commit d626cb5

Browse files
authored
Merge pull request #123 from FSoft-AI4Code/fix/mermaid-thread-exit-hang
Fix: hung mermaid validation request blocks process exit
2 parents 3e3d848 + fd43f9c commit d626cb5

1 file changed

Lines changed: 30 additions & 1 deletion

File tree

‎codewiki/src/be/utils.py‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,35 @@ def _parse_via_mermaid_py(diagram_content: str) -> str:
233233
return str(e)
234234

235235

236+
def _run_in_daemon_thread(fn, *args) -> "asyncio.Future":
237+
"""Run fn in a daemon thread and return an awaitable for its result.
238+
239+
Unlike asyncio.to_thread, a thread left hanging after wait_for times out
240+
(mermaid-py's requests.get has no timeout) does not block interpreter exit.
241+
"""
242+
import threading
243+
244+
loop = asyncio.get_running_loop()
245+
fut = loop.create_future()
246+
247+
def _set(setter, value):
248+
if not fut.done():
249+
setter(value)
250+
251+
def _worker():
252+
try:
253+
setter, value = fut.set_result, fn(*args)
254+
except BaseException as e:
255+
setter, value = fut.set_exception, e
256+
try:
257+
loop.call_soon_threadsafe(_set, setter, value)
258+
except RuntimeError:
259+
pass # loop already closed; nobody is waiting any more
260+
261+
threading.Thread(target=_worker, daemon=True).start()
262+
return fut
263+
264+
236265
async def validate_single_diagram(diagram_content: str, diagram_num: int, line_start: int) -> str:
237266
"""
238267
Validate a single mermaid diagram.
@@ -258,7 +287,7 @@ async def validate_single_diagram(diagram_content: str, diagram_num: int, line_s
258287
return ""
259288
try:
260289
core_error = await asyncio.wait_for(
261-
asyncio.to_thread(_parse_via_mermaid_py, diagram_content),
290+
_run_in_daemon_thread(_parse_via_mermaid_py, diagram_content),
262291
timeout=15.0,
263292
)
264293
except asyncio.TimeoutError:

0 commit comments

Comments
 (0)