Audit finding (read-only review of gamdl 3.8.5, commit 478c3f2). Cross-checked by two models; both judge it real.
Lens: reliability
Suggested grade: Strong (luna: high; grok: medium)
Evidence
gamdl/downloader/base.py:281-285 — the async parent waits for the yt-dlp child with no deadline, no stall detection, no termination:
while process.is_alive():
await asyncio.sleep(0.1)
process.join()
gamdl/downloader/base.py:34-43 — YoutubeDL params set quiet/overwrites/concurrent_fragment_downloads but no socket timeout tuning.
gamdl/utils.py:15-20 — async_subprocess (N_m3u8DL-RE mode) runs asyncio.create_subprocess_exec then await proc.communicate() with no asyncio.wait_for and no timeout.
Impact: a wedged child (trickling connection, deadlock, stuck ffmpeg/file I/O) hangs the entire CLI indefinitely with no message and no cleanup, in both download modes. The user's only recourse is Ctrl+C, which abandons the temp dir.
Model verdicts
- luna (gpt-5.6-luna): real, high. "Wrap communicate() in a timeout and, on expiry, terminate/kill and reap the subprocess. Also add a timeout around the multiprocessing child."
- grok (grok-4.6): real, medium — with a correction the ticket adopts: "yt-dlp already defaults socket_timeout to 20 seconds per socket read/connect. Adding socket_timeout 30 is almost the default and does not bound the parent wait. It also does nothing for N_m3u8DL-RE... Bound the process, not yt-dlp's sockets." (Dissent noted: the original proposal to set
socket_timeout was downgraded to optional.)
Fix direction: bound the process, not the socket: give the parent wait a deadline (overall cap or no-progress/no-output window), then terminate() + grace + kill() and log which track/tool stalled; wrap communicate() in asyncio.wait_for with the same kill sequence for N_m3u8DL-RE. Keep yt-dlp's default socket timeout.
Adopt as upstream contribution candidate? (adopt / adapt / reject)
Audit finding (read-only review of gamdl 3.8.5, commit 478c3f2). Cross-checked by two models; both judge it real.
Lens: reliability
Suggested grade: Strong (luna: high; grok: medium)
Evidence
gamdl/downloader/base.py:281-285— the async parent waits for the yt-dlp child with no deadline, no stall detection, no termination:gamdl/downloader/base.py:34-43— YoutubeDL params set quiet/overwrites/concurrent_fragment_downloads but no socket timeout tuning.gamdl/utils.py:15-20—async_subprocess(N_m3u8DL-RE mode) runsasyncio.create_subprocess_execthenawait proc.communicate()with noasyncio.wait_forand no timeout.Impact: a wedged child (trickling connection, deadlock, stuck ffmpeg/file I/O) hangs the entire CLI indefinitely with no message and no cleanup, in both download modes. The user's only recourse is Ctrl+C, which abandons the temp dir.
Model verdicts
socket_timeoutwas downgraded to optional.)Fix direction: bound the process, not the socket: give the parent wait a deadline (overall cap or no-progress/no-output window), then
terminate()+ grace +kill()and log which track/tool stalled; wrapcommunicate()inasyncio.wait_forwith the same kill sequence for N_m3u8DL-RE. Keep yt-dlp's default socket timeout.Adopt as upstream contribution candidate? (adopt / adapt / reject)