Skip to content

feat(memory): host-aware --max-memory on pipeline commands (#381) - #403

Merged
nh13 merged 1 commit into
feat-runallfrom
feat-runall-11-host-aware-max-memory
Jun 15, 2026
Merged

nh13 merged 1 commit into
feat-runallfrom
feat-runall-11-host-aware-max-memory

Conversation

@nh13

@nh13 nh13 commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

Makes --max-memory host-aware across all pipeline commands and reworks the memory-budget resolution so a run self-throttles to fit the host instead of OOM-ing (#380/#381).

  • --max-memory auto detects host RAM (cgroup-aware: min(cgroup_limit, physical)), subtracts --memory-reserve, and caps the per-thread floor to what's actually available — so auto never multiplies the floor past physical memory.
  • Per-thread vs fixed-total budgeting is explicit via --memory-per-thread; both paths use checked_mul and surface a clear overflow error.
  • Unifies the shared QueueMemoryOptions (used by group, dedup, codec, clip, correct, zipper, filter, runall) with fgumi sort's --max-memory semantics; legacy --queue-memory / --queue-memory-per-thread / --queue-memory-limit-mb remain as hidden aliases.

Folded fixes

This commit absorbs two bug fixes that live in the code it introduces (squashed into this single commit; they no longer ship as standalone PRs):

Tests

80 memory/round-trip/per-thread unit tests cover: default 768 MiB/thread, single-thread fixed footprint, auto bounding by host (never oversubscribes a small host; uses the floor when the host is ample), fixed-budget independence from host, reserve shrinking, deprecated-alias behaviour, and overflow → error on every multiply path.

Stack context

Part of the issue #330 unified-pipeline landing onto feat-runall (one commit per PR). Dual-reviewed before push.

Give the shared QueueMemoryOptions the same memory surface as fgumi sort:
--max-memory (with `auto`), --memory-reserve, and --memory-per-thread. Under
--max-memory auto the budget is detected from cgroup-aware host memory minus the
reserve, so it shrinks to fit the host and pipeline commands self-throttle
instead of OOM-ing on fixed-RAM hosts. The MemoryLimit/MemoryReserve types,
parsers, and budget resolution move from commands::sort into commands::common so
the sort buffer and pipeline-queue surfaces stay in lockstep; the legacy
--queue-memory / --queue-memory-per-thread / --queue-memory-limit-mb flags remain
accepted as hidden deprecated aliases.

This reconciles #381 onto the #330 typed-step pipeline, preserving #330's lean
single-thread queue-memory default: QueueMemoryOptions::max_memory is
Option<MemoryLimit> (None = unset) so calculate_memory_limit can still return the
lean 64 MiB total at --threads 1 while honoring an explicit --max-memory at any
thread count. The standalone sort path and the streaming/fused sort step now call
the moved resolve_memory_budget; the forced-spill path is unchanged (still reads
a fixed sort buffer × threads).

Also folds an Item 2 test-union residual surfaced by this change's ci-test run:
restore main's group sort-order error message naming the SO:unsorted, GO:query,
and SS:template-coordinate header fields (matches is_template_coordinate_sorted),
so test_group_rejects_extract_output_without_sort_step passes again.
@nh13
nh13 temporarily deployed to github-actions June 15, 2026 10:02 — with GitHub Actions Inactive
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.56322% with 5 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (feat-runall@a7ce2d0). Learn more about missing BASE report.

Files with missing lines Patch % Lines
src/lib/commands/common.rs 99.07% 3 Missing ⚠️
src/lib/pipeline/chains/builder.rs 80.00% 2 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff               @@
##             feat-runall     #403   +/-   ##
==============================================
  Coverage               ?   93.20%           
==============================================
  Files                  ?      138           
  Lines                  ?    54400           
  Branches               ?        0           
==============================================
  Hits                   ?    50703           
  Misses                 ?     3697           
  Partials               ?        0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nh13
nh13 merged commit 82a712e into feat-runall Jun 15, 2026
10 checks passed
@nh13
nh13 deleted the feat-runall-11-host-aware-max-memory branch June 15, 2026 10:13
nh13 added a commit that referenced this pull request Jun 18, 2026
Give the shared QueueMemoryOptions the same memory surface as fgumi sort:
--max-memory (with `auto`), --memory-reserve, and --memory-per-thread. Under
--max-memory auto the budget is detected from cgroup-aware host memory minus the
reserve, so it shrinks to fit the host and pipeline commands self-throttle
instead of OOM-ing on fixed-RAM hosts. The MemoryLimit/MemoryReserve types,
parsers, and budget resolution move from commands::sort into commands::common so
the sort buffer and pipeline-queue surfaces stay in lockstep; the legacy
--queue-memory / --queue-memory-per-thread / --queue-memory-limit-mb flags remain
accepted as hidden deprecated aliases.

This reconciles #381 onto the #330 typed-step pipeline, preserving #330's lean
single-thread queue-memory default: QueueMemoryOptions::max_memory is
Option<MemoryLimit> (None = unset) so calculate_memory_limit can still return the
lean 64 MiB total at --threads 1 while honoring an explicit --max-memory at any
thread count. The standalone sort path and the streaming/fused sort step now call
the moved resolve_memory_budget; the forced-spill path is unchanged (still reads
a fixed sort buffer × threads).

Also folds an Item 2 test-union residual surfaced by this change's ci-test run:
restore main's group sort-order error message naming the SO:unsorted, GO:query,
and SS:template-coordinate header fields (matches is_template_coordinate_sorted),
so test_group_rejects_extract_output_without_sort_step passes again.

This branch was previously deployed

1 inactive deployment
github-actions — eb56e66a Deployed Jun 15, 2026 by nh13 via coverage #1625
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant