Skip to content

refactor: spawn child processes with tokio::process - #587

Open
lvaroqui wants to merge 1 commit into
mainfrom
cod-3863-chore-avoid-blocking-in-runner
Open

lvaroqui wants to merge 1 commit into
mainfrom
cod-3863-chore-avoid-blocking-in-runner

Conversation

@lvaroqui

@lvaroqui lvaroqui commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Spawn the benchmark, build and MongoDB tracer processes with tokio::process instead of std::process, so waiting on a child no longer blocks the runtime.

RunnerFifo::handle_fifo_messages now selects on incoming FIFO commands and on child.wait(). Previously it only checked try_wait() after recv_cmd had been idle for 1s, so each run returned up to a second after the benchmark process exited.

Commands still unread when the child exits can be dropped, as before: the old loop could also time out, receive a command and see the exit in try_wait() before reading it. Now the loop returns as soon as child.wait() resolves, and if a command and the exit are ready at the same time select! picks one at random. What actually prevents lost commands is the ack: integrations send each command and block until the runner acks it, so they can't exit with a command unread.

Child stdout and stderr are taken back as blocking files (take_blocking_stdio, built on into_owned_fd, which clears O_NONBLOCK) and drained on blocking threads, as before.

Closes COD-3863

@lvaroqui
lvaroqui force-pushed the cod-3863-chore-avoid-blocking-in-runner branch from ac23d7e to 3a5dbf0 Compare October 15, 2026 14:32
Benchmark, build and MongoDB tracer processes now run as
tokio::process::Child, so waiting on them no longer blocks the async
runtime.

The FIFO command handler selects on incoming commands and on the child
exiting, instead of checking try_wait only after a 1s idle timeout.
A run therefore returns as soon as the benchmark process exits, rather
than up to a second later.

Child stdout and stderr are converted back to blocking files with
into_owned_fd and read on blocking threads, so draining the logs does
not depend on the current_thread runtime driving IO.

Closes COD-3863
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lvaroqui
lvaroqui force-pushed the cod-3863-chore-avoid-blocking-in-runner branch from 3a5dbf0 to 2c52924 Compare October 15, 2026 14:41
@codspeed

codspeed Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ 8 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

✅ 41 untouched benchmarks
⏩ 6 skipped benchmarks1


Comparing cod-3863-chore-avoid-blocking-in-runner (2c52924) with main (9e74317)

Open in CodSpeed

Footnotes

  1. 6 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@lvaroqui
lvaroqui marked this pull request as ready for review October 15, 2026 14:45
@greptile-apps

greptile-apps Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[High impact] The PR appears safe to merge.

Summary

Moves benchmark, build, and MongoDB tracer processes to tokio::process.

  • The runner returns profiling results as soon as the benchmark child exits.
  • Benchmark, build, and tracer child processes use Tokio while logs stay on blocking readers.

No actionable issues were found.

lvaroqui explicitly identifies dropping unread FIFO commands at child exit as intentional. The stated safeguard is that integrations wait for a reply before continuing.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Spawn child with Tokio] --> B[Drain output on blocking threads]
  A --> C[Wait for FIFO command or child exit]
  C -->|Command| D[Handle command and send reply]
  D --> C
  C -->|Child exits| E[Return timestamps and exit status]
  B --> F[Finish draining output]
  E --> F
  F --> G[Return result]
Loading

Reviews (1) · Last reviewed commit: "refactor: spawn child processes with tok..." · Reviewed by Greptile

@lvaroqui
lvaroqui requested a review from not-matthias October 15, 2026 14:51
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