Parallelize SSE search and add concurrency controls#132
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the BGP search execution logic into a shared, configurable executor and wires it into the SSE server path to enable parallel MRT processing. It also introduces concurrency controls at both the execution level (rayon thread count) and the server admission-control level (rejecting excess concurrent SSE searches with HTTP 429).
Changes:
- Added a shared search executor API (
SearchExecutionOptions,SearchSink,SearchOutcome/ExitReason) and migratedSearchLens::search_with_progressto use it. - Parallelized SSE
/api/v1/search/streamby delegating to the shared executor while keeping bounded-channel backpressure and disconnect cancellation. - Added configuration/CLI flags for
search_concurrencyandserver_max_concurrent_searches, plus a 429 error path.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lens/search/mod.rs | Introduces shared executor/sink abstractions and implements parallel execution with max-results/timeout/cancel controls. |
| src/server/search.rs | Switches SSE worker to shared executor, adds per-request concurrency selection and semaphore-based admission control. |
| src/server/mod.rs | Adds Semaphore to ServerState for limiting concurrent SSE searches. |
| src/server/http.rs | Adds TooManyRequests API error code and a helper constructor returning HTTP 429. |
| src/config.rs | Adds search_concurrency and server_max_concurrent_searches to MonocleConfig with defaults and parsing. |
| src/bin/monocle.rs | Adds server CLI overrides for --concurrency and --max-concurrent-searches. |
| src/bin/commands/search.rs | Adds local search --concurrency and installs a local rayon pool when set. |
| src/bin/commands/config.rs | Surfaces new search/server concurrency defaults in config command output. |
| src/server/README.md | Documents new config keys and CLI flags for concurrency and SSE admission control. |
| CHANGELOG.md | Updates unreleased notes to reflect parallel SSE search and new concurrency controls. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Addressed review comments in de872e1:
Validated with:
|
|
Addressed the latest timeout review comments in 3729772:
Validated with:
|
| let max_concurrent_searches = config.server_max_concurrent_searches; | ||
| let state = ServerState { | ||
| config: Arc::new(config), | ||
| search_permits: Arc::new(Semaphore::new(max_concurrent_searches)), | ||
| }; |
| pub enum SearchControl { | ||
| Continue, | ||
| Stop, | ||
| } |
| match options.concurrency { | ||
| Some(n) if n > 0 => { | ||
| let pool = rayon::ThreadPoolBuilder::new().num_threads(n).build()?; | ||
| pool.install(run); | ||
| } |
| for elem in parser { | ||
| if search_should_stop(&state) { | ||
| break; | ||
| } | ||
|
|
||
| batch.push(elem); | ||
| if batch.len() >= state.batch_size { | ||
| let accepted = emit_search_batch(&state, index, &url, &collector, &mut batch); | ||
| file_messages += accepted; | ||
| } |
|
Addressed latest review comments in 2997feb:
Validated with:
|
…, update config example - Set SearchExecutionOptions::default() batch_size to 64 instead of 0 (which was clamped to 1), reducing per-element allocations in the library search path. - Suppress SearchProgress::Completed in SseSearchSink::on_progress to avoid sending a redundant progress-level completion event before the terminal SearchStreamEvent::Completed. - Add search_concurrency and server_max_concurrent_searches to monocle.toml.example to match documentation in config.rs and server/README.md.
Resolves #131.
search_concurrency,--concurrency, and SSE admission control viaserver_max_concurrent_searches/ 429.Tested:
cargo fmtcargo clippy --all-features -- -D warningscargo test --all-features