Skip to content

feat(client): Add put_path for lazy file descriptor opening#415

Merged
jan-auer merged 2 commits intomainfrom
feat/put-path-ulimit
Apr 1, 2026
Merged

feat(client): Add put_path for lazy file descriptor opening#415
jan-auer merged 2 commits intomainfrom
feat/put-path-ulimit

Conversation

@jan-auer
Copy link
Copy Markdown
Member

@jan-auer jan-auer commented Mar 30, 2026

Opening tokio::fs::File eagerly via put_file and pushing many builders into a ManyBuilder holds all file descriptors open simultaneously — easily exhausting macOS's default ulimit of 256.

Session::put_path accepts a path and defers the open until the operation is submitted. classify() uses tokio::fs::metadata (no fd) to size-check path bodies; maybe_compress (now async) opens the file at the point of consumption, within the active concurrency window.

Also fixes two related issues found along the way:

  • Stream bodies were routed through the batch endpoint despite having unknown size; they now always go individual
  • Buffer bodies were not size-checked and could exceed MAX_BATCH_PART_SIZE

Fixes FS-325

Fixes FS-325

Opening tokio::fs::File eagerly via put_file and pushing many such
builders into a ManyBuilder causes all file descriptors to be held open
simultaneously — easily exhausting macOS's default ulimit of 256.

Introduces Session::put_path, which accepts a path and defers the open
until the operation is actually submitted. classify() uses
tokio::fs::metadata (no fd) to size-check path bodies, and maybe_compress
(now async) opens the file at the point of consumption, within the active
concurrency window.

Also routes Stream bodies through the individual endpoint (unknown size)
and applies the batch size check to Buffer bodies.
@jan-auer jan-auer requested a review from a team as a code owner March 30, 2026 14:28
@linear-code
Copy link
Copy Markdown

linear-code bot commented Mar 30, 2026

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 30, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (client) Add put_path for lazy file descriptor opening by jan-auer in #415

Internal Changes 🔧

  • (client) Refactor many API into combinator pipeline by lcian in #391
  • (config) Collapse dual storage fields into a single StorageConfig by jan-auer in #384

🤖 This preview updates automatically when you update the PR.

Comment on lines 518 to 522
let op = BatchOperation::Insert {
key,
metadata,
body: PutBody::File(file),
body,
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure you need the copy. i think you can move the original op argument, or assign a name to the current match case with @:

match op {
    insert @ BatchOperation::Insert {
        ...
    } => {
        ...
        if size.is_some_and(|s| s <= MAX_BATCH_PART_SIZE as u64) {
            Classified::Batchable(op) // I think you can move the original argument here
        } else {
            Classified::Individual(insert) // or you can reference a named pattern
        }
    }
}

Copy link
Copy Markdown
Member Author

@jan-auer jan-auer Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this doesn't copy data. It's a destructure + move on the stack that is fully optimized out by the compiler.

Using insert @ ... is sadly not possible since we move the key out in the error case. The insert variable's type is the enum, not the variant. We would have to bind the individual fields we read with ref like so:

BatchOperation::Insert {
    ref key,
    ref metadata,
    ref body,
}

The problem then becomes that we need to clone key in the error case. I had this at first, and to avoid the clone creates even worse code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this comment is stale now

@jan-auer jan-auer merged commit f788b5d into main Apr 1, 2026
22 checks passed
@jan-auer jan-auer deleted the feat/put-path-ulimit branch April 1, 2026 08:53
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.

2 participants