Skip to content

Reliability: unbounded wait on download subprocesses - a stalled yt-dlp/N_m3u8DL-RE child hangs the CLI forever #6

Description

@JavaGT

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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions