Skip to content

perf(io): stop fdatasync-ing output files on close - #1054

Open
nh13 wants to merge 1 commit into
mainfrom
nh/drop-output-sync
Open

nh13 wants to merge 1 commit into
mainfrom
nh/drop-output-sync

Conversation

@nh13

@nh13 nh13 commented Oct 10, 2026

Copy link
Copy Markdown
Member

Closing an output file fdatasync-ed it before the checked close(2) (added in #1047), so the final close waited out the whole write-back: closing a 49 GB coordinate-sorted output took 61.5 s with the sync against 20–28 s without it (c7g.4xlarge, gp3). That tail was the largest source of run-to-run variance in the sort benchmarks. fgumi 0.7.0 did not sync its outputs, and this restores that behaviour deliberately. It differs from htslib, and so samtools, whose bgzf_close reaches fdatasync through hflush. Durability against a host crash is left to the caller.

What changed

  • OutputFile::close is now just the checked close. The sync, the list of "sync unsupported" errnos it needed, and OutputFile::unsynced (added in fix(io): sync and check close of output files #1047, never released) are removed; callers use OutputFile::from.
  • The temp-file close before a rename (BAI index, sort merge output) is close-only too. Those renames stay atomic against a process failure but not against a host crash or power loss, and their docs now say so. "sync/close" error messages now say "close".
  • A test scans every source file in the workspace and fails if the set of sync_data / sync_all / fdatasync / fsync / F_FULLFSYNC calls differs from the two that remain (the metrics writer's temp-and-rename and review's staged grouped BAM, both unchanged here).

Kept from #1047

The checked close and its error reporting (EINTR treated as success), short-write detection through the checked flush and close of every output sink, the pooled writers' failure when the I/O writer ends short of the blocks its PermitPool issued, and the rejection of block serials the pool did not issue.

Output: unchanged. An error the OS reports only after close (deferred write-back) is no longer surfaced; errors reported at close still fail the command.

Closing an output file synced its data to storage before the checked
close(2), which made the final close wait out the whole write-back:
closing a 49 GB coordinate-sorted output took 61.5 s with the sync
against 20-28 s without it (c7g.4xlarge, gp3). fgumi 0.7.0 did not sync
its outputs, and this restores that behaviour deliberately. It differs
from htslib, and so samtools, whose bgzf_close reaches fdatasync through
hflush. Durability against a host crash is left to the caller.

OutputFile::close is now just the checked close. The sync, the skip list
of "sync unsupported" errnos it needed, and the OutputFile::unsynced
constructor (added in #1047 and never released) are removed; callers use
OutputFile::from. The temp-file close before a rename (BAI index, sort
merge output) is likewise close-only, and "sync/close" error messages
now say "close". Those renames stay atomic against a failure of the
process, but no longer against a host crash or power loss, and their
docs now say so.

Kept from the change that added the sync: the checked close and its
error reporting (EINTR treated as success), short-write detection
through the checked flush and close of every output sink, the pooled
writers' failure when the I/O writer ends short of the blocks its
PermitPool issued, and the rejection of block serials the pool did not
issue.

Two outputs still sync, for reasons of their own and unchanged here: the
metrics writer's temp-and-rename (fgumi-metrics, small files) and
review's staged grouped BAM. A test scans every source file in the
workspace and fails if the set of sync_data, sync_all, fdatasync, fsync
or F_FULLFSYNC calls differs from those two, so re-adding the sync to
OutputFile::close (or anywhere else) fails it, and so does removing an
allowed one without updating the list.

Changes output for: none. An error the OS reports only after close
(deferred write-back) is no longer surfaced; errors reported at close
still fail the command.
@nh13
nh13 deployed to github-actions October 10, 2026 22:18 — with GitHub Actions Active
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: fulcrumgenomics/fgumi/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Essentials
  • Run ID: d66d51c8-f4f7-4536-a372-664f20ba53a7

📥 Commits

Reviewing files that changed from the base of the PR and between cf9c003 and 008a2f8.


📒 Files selected for processing (11)
  • crates/fgumi-bam-io/src/output.rs
  • crates/fgumi-bam-io/src/writer.rs
  • crates/fgumi-pipeline-io/src/sink/mod.rs
  • crates/fgumi-pipeline-io/src/sink/write_bgzf.rs
  • crates/fgumi-pipeline-io/src/sink/write_raw.rs
  • crates/fgumi-sort/src/bgzf_io.rs
  • crates/fgumi-sort/src/external.rs
  • crates/fgumi-sort/src/pooled_bam_writer.rs
  • src/lib/simulate/fastq_writer.rs
  • src/lib/simulate/mod.rs
  • src/lib/simulate/parallel_gzip_writer.rs

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.



⚠️ A high-level summary could not be generated for this review. CodeRabbit will regenerate it on the next update, or you can request a refresh with @coderabbitai summary.

Walkthrough

Output files now check close errors without syncing data first. The change removes OutputFile’s sync controls, updates temp-file persistence to close before rename, and revises output documentation and error contexts to describe close handling and durability limits.

Changes

Output close handling

Layer / File(s) Summary
OutputFile close behavior
crates/fgumi-bam-io/src/output.rs
OutputFile no longer syncs before close, and its public unsynced constructor is removed. Close errors remain checked. A workspace test checks that Rust sources contain only the allowed sync calls.
Close before persistence and indexing
crates/fgumi-sort/src/external.rs, crates/fgumi-bam-io/src/writer.rs
Merge output closes its temporary file before rename. Writer documentation describes checked close and states that the temporary index is not synced before rename.
Downstream close descriptions
crates/fgumi-pipeline-io/src/sink/*, crates/fgumi-sort/src/{bgzf_io.rs,pooled_bam_writer.rs}, src/lib/simulate/*
Documentation and error contexts now describe output flushing and closing without claiming that output data is synced.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Suggested labels: fgumi sort

Merge Risk: ⚪ Minimal · up to 008a2

Output close no longer waits for data to sync, as intended. The checked-close behavior remains, and no issue requiring a fix before merge was identified.

Pre-merge checks | Passed 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check Passed The title uses valid Conventional Commit syntax, has the allowed perf type, uses a lowercase imperative description, and accurately states the main change.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@nh13

nh13 commented Oct 10, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Oct 10, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews paused.

@codecov

codecov Bot commented Oct 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.33333% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.59%. Comparing base (40bae7e) to head (008a2f8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
crates/fgumi-bam-io/src/output.rs 92.98% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1054      +/-   ##
==========================================
- Coverage   96.60%   96.59%   -0.02%     
==========================================
  Files         304      304              
  Lines      155704   155953     +249     
==========================================
+ Hits       150419   150635     +216     
- Misses       5285     5318      +33     

☔ 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 commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

This branch was successfully deployed

1 active deployment
github-actions — 008a2f82 Deployed Oct 10, 2026 by nh13 via coverage #4956
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