Skip to content

Cache downloads no longer time out after 60 seconds (Z22a) - #26

Merged
Thiyaghessan merged 2 commits into
mainfrom
z22/download-timeout
Sep 21, 2026
Merged

Thiyaghessan merged 2 commits into
mainfrom
z22/download-timeout

Conversation

@Thiyaghessan

Copy link
Copy Markdown
Collaborator

nccs-contracts BACKLOG Z22 (a).

Problem. nccs_read(cache = TRUE) downloads the 641 MB geocoded Unified BMF with utils::download.file(), which stops after R's default 60-second timeout. On an ordinary connection the copy never completed, the function quietly read from S3 instead, and unfinished .part files accumulated in the cache folder. The CORE partition download had the same shape.

Fix. One helper, .download_to_cache(), used by both call sites:

  • uses the curl package when it is installed (already a suggested dependency; no timeout of its own),
  • otherwise raises options(timeout) to at least an hour for the download only and restores it afterwards,
  • removes a stale .part before starting and on failure, so nothing piles up.

No change to the public interface. withr added to Suggests for the tests. Three tests (success, failure cleanup, timeout restore on the fallback path); full suite passes.

🤖 Generated with Claude Code

utils::download.file() honours R's 60-second default timeout, so the
641 MB geocoded BMF never finished downloading on an ordinary connection,
nccs_read() silently fell back to S3, and .part files piled up. A shared
helper now uses the curl package when installed (no such limit) and
otherwise raises the timeout to an hour for the download only; a stale or
failed partial file is always removed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Thiyaghessan Thiyaghessan added the contracts-ack PR touches the read/publish surface but changes no contract (ADR 0022 guard relief) label Sep 21, 2026
Per review: download.file() can report failure through its return value
without raising an error, leaving a partial file that would then have been
renamed into the cache. The status is now checked before the rename. The
fallback path is exercised in tests via a use_curl argument and a mocked
download.file(), rather than skipped when curl is installed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Thiyaghessan

Copy link
Copy Markdown
Collaborator Author

Fixed. The fallback path now checks download.file()'s return value and treats anything but 0 as a failure, so a partial file is removed rather than renamed into the cache. To test that path regardless of whether curl is installed, the helper takes a use_curl argument (default: curl when available); the tests pass FALSE and mock utils::download.file to write a partial file and return status 1, then assert the error, no cached file, and no .part left. The old skipping test is replaced by two that always run (timeout restore; missing source). Full suite passes.

@Thiyaghessan
Thiyaghessan merged commit df3c8ea into main Sep 21, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contracts-ack PR touches the read/publish surface but changes no contract (ADR 0022 guard relief)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant