Skip to content

ref(service): Replace upfront batch reservation with per-op bulk permits#563

Merged
jan-auer merged 11 commits into
mainfrom
ref/concurrency-stream
Jul 22, 2026
Merged

ref(service): Replace upfront batch reservation with per-op bulk permits#563
jan-auer merged 11 commits into
mainfrom
ref/concurrency-stream

Conversation

@jan-auer

@jan-auer jan-auer commented Jul 20, 2026

Copy link
Copy Markdown
Member

The streaming executor previously reserved a bulk window of permits upfront. This PR replaces that model with per-operation permit acquisition through a new bulk concurrency class on the limiter.

Each streaming operation now individually acquires a bulk permit via acquire_bulk, which waits on two semaphores sequentially:

  1. a dedicated bulk semaphore with lower budget
  2. the regular inner semaphore to guard overall execution concurrency

Note that this purposefully does not acquire the queue permit as to not take away queueing slots for regular requests.

Permits are acquired sequentially, and only operations with permit are parallelized. This ensures fairness between concurrent batch requests and prevents a large batch from racing for all permits at once.

The bulk budget sets a safe operating point: below this level, there should be little-to-no performance degradation, leaving room for more tasks to be admitted via the queue before rejection is necessary. In config this is defaulted to 60% of max_concurrency.

See also #562
Ref FS-447

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.67%. Comparing base (0bc8c3f) to head (84c63b0).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #563      +/-   ##
==========================================
+ Coverage   87.55%   87.67%   +0.12%     
==========================================
  Files          93       93              
  Lines       14969    15113     +144     
==========================================
+ Hits        13106    13251     +145     
+ Misses       1863     1862       -1     
Components Coverage Δ
Rust Backend 92.45% <100.00%> (+0.10%) ⬆️
Rust Client 79.89% <ø> (ø)
Python Client 90.20% <ø> (ø)

☔ 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.

@linear-code

linear-code Bot commented Jul 20, 2026

Copy link
Copy Markdown

FS-447

Comment thread objectstore-server/src/config.rs
@jan-auer
jan-auer marked this pull request as ready for review July 21, 2026 11:03
@jan-auer
jan-auer requested a review from a team as a code owner July 21, 2026 11:03
Comment thread objectstore-service/src/concurrency.rs
Comment thread objectstore-service/src/concurrency.rs
Comment thread objectstore-service/src/streaming.rs
Comment thread objectstore-service/src/concurrency.rs
Comment thread objectstore-service/src/streaming.rs
Comment thread objectstore-service/src/concurrency.rs

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 5 total unresolved issues (including 4 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 21d1d0d. Configure here.

Comment thread objectstore-service/src/concurrency.rs

@lcian lcian left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good to me after addressing comments, feel free to merge and deploy, as we discussed this extensively and tested it in sandbox.

/// `1s`
#[serde(with = "humantime_serde")]
pub concurrency_queue_timeout: Duration,
pub concurrency_timeout: Duration,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is technically a breaking change. We cannot use serde(alias) here, as this breaks with figment.

Comment thread objectstore-server/src/config.rs
@jan-auer

jan-auer commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

I've changed the implementation for regular permits now, so that the queue semaphore just covers the wait: it's only acquired while acquiring the actual task permit, and then immediately released. Previously it wrapped the lifetime of the task permit, which broke with bulk requests not holding a queue permit.

The new approach comes with different behavior: It isolates waiting bulk tasks (i.e. batch requests, but later maybe background tasks) from queued requests. Also, even with queue configured at 0 (default), this means batch requests and background tasks will still queue up internally (without a limit).

I'm a bit torn about this - the previous wrapping approach seemed cleaner to me, although bypassing the queue is the more future-proof behavior.

@jan-auer
jan-auer merged commit e88b7f8 into main Jul 22, 2026
27 checks passed
@jan-auer
jan-auer deleted the ref/concurrency-stream branch July 22, 2026 07:10
jan-auer added a commit that referenced this pull request Jul 22, 2026
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