Skip to content

fix: AggregateFITS leaked one file handle per HDU per result (crash at ~500 results)#1386

Merged
Jammy2211 merged 1 commit into
mainfrom
feature/aggregate-images-fits
Jul 17, 2026
Merged

fix: AggregateFITS leaked one file handle per HDU per result (crash at ~500 results)#1386
Jammy2211 merged 1 commit into
mainfrom
feature/aggregate-images-fits

Conversation

@Jammy2211

Copy link
Copy Markdown
Collaborator

Summary

AggregateFITS (the fits_make catalogue workflow) leaked one file handle per requested HDU per result: _hdus called result.value(...) — a fresh fits.open — for every HDU, and the returned ImageHDUs kept the memmaps (and so the handles) alive. Measured: 200 leaked fds for 100 results × 2 HDUs. At the default ulimit of 1024, extract_fits/output_to_folder crashes with "Too many open files" around ~500 results — the Euclid use case is 3000. extract_csv had the same one-leak-per-result pattern.

Fix: each source fits file is opened once per result (not once per HDU), extracted data is copied out of the memmap, and the source is closed deterministically. Verified: 0 leaked fds at 100 results, byte-identical output (201 HDUs), and 19% faster per result at 2 HDUs in an interleaved A/B (the win grows with HDU count — the workflow guide uses 4).

Found by the new aggregate_images/aggregate_fits profiling stages (autofit_workspace_test PR) — the last uncovered leg of the #1375 catalogue workflow (csv was profiled and sped up in #1376; png/fits never were). AggregateImages profiled clean: ~1.5 ms/result, already caches one open per subplot type per result — no fruit taken there.

API Changes

None — bug fix only: no behaviour change other than handles being closed (and extract_csv tables being materialised rather than possibly memmap-backed).
See full details below.

Test Plan

  • pytest test_autofit/ — 1495 passed, 1 skipped
  • New regression test test_aggregate_fits.py::test_extract_fits_closes_files (fd counting, /proc-guarded)
  • Empirical: 100-result extract_fits leaks 0 fds (was 200); output identical
Full API Changes (for automation & release notes)

Changed Behaviour

  • AggregateFITS._hdus — one fits.open per unique source file per result; data copied out of the memmap; sources closed in a finally.
  • AggregateFITS.extract_csv — source fits closed per result; returned Tables are materialised copies.

Generated by the PyAutoLabs agent workflow.

_hdus opened the source fits once per requested HDU (a fresh
fits.open via result.value) and the returned ImageHDUs kept the
memmaps alive — 2 leaked fds/result measured; extract_fits crashes
on "Too many open files" around ~500 results at the default ulimit.
extract_csv leaked one handle per result the same way.

Each source file is now opened once per result, data copied out of
the memmap, and closed in a finally. 19% faster at 2 HDUs
(interleaved A/B); output byte-identical. fd-count regression test.

Found by the new aggregate_images/aggregate_fits profiling stages
(#1385).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Jammy2211 Jammy2211 added the pending-release PR queued for the next release build label Jul 17, 2026
@Jammy2211
Jammy2211 merged commit bec3734 into main Jul 17, 2026
5 checks passed
@Jammy2211
Jammy2211 deleted the feature/aggregate-images-fits branch July 17, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending-release PR queued for the next release build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant