#1469·gopeed

HTTP Resolve prefetch files can survive process exit and exhaust disk space

Author: PseudoataraxiaCreated Sep 5, 2026Updated Sep 5, 2026

Description(required)

For range-capable HTTP resources, Fetcher.Resolve starts asyncPrefetch, which writes the reusable Resolve response to a named gopeed-prefetch-* temporary file.

Current main has two independent lifetime gaps:

  1. The named temporary file survives a crash or forced process termination.
  2. A completed Resolve result abandoned by a REST/UI client remains in fetcherCache; downloader shutdown does not drain that cache.

A deterministic baseline reproduction on current main is:

bash
TMPDIR="$(mktemp -d)" go test ./internal/protocol/http -run '^TestFetcher_Patch_Labels$' -count=1 -v

The test passes but leaves a 209,715,200-byte gopeed-prefetch-* file in TMPDIR. Repeated test runs or abandoned Resolve operations therefore accumulate large orphaned files.

Expected behavior

  • No named prefetch data should survive normal close, normal process exit, or forced termination.
  • Completed Resolve results that a client abandons should have an explicit, idempotent release operation.
  • Downloader shutdown should drain and close all cached Resolve fetchers.
  • Stopping prefetch should interrupt a blocked response-body read and wait for its worker before consuming or closing the backing storage.

Scope

This report concerns leaked/orphaned backing storage. The current one-time-URL fallback may still stage a full response while the process remains alive. A TTL, byte budget, or backpressure policy is a separate design issue: a simple hard cap would break the one-time-URL fallback that prefetch currently preserves.

Draft #1451 partially drains the Resolve cache, but it does not make prefetch storage crash-safe and includes broader unrelated changes.

App Version

Current main at 3be8db664c1f8e64e088afe69abcb12c795f63af.

OS Version

macOS

Snapshots

N/A

Log

The deterministic reproduction and leftover-file size are included above.