Skip to content

[runtime] Support criterion::AsyncExecutor + rayon::ThreadPool#778

Merged
patrick-ogrady merged 26 commits into
mainfrom
criterion-runtime
Apr 22, 2025
Merged

[runtime] Support criterion::AsyncExecutor + rayon::ThreadPool#778
patrick-ogrady merged 26 commits into
mainfrom
criterion-runtime

Conversation

@patrick-ogrady
Copy link
Copy Markdown
Contributor

@patrick-ogrady patrick-ogrady commented Apr 18, 2025

Related: #727

The complexity here is that criterion needs to be able to create runtimes but the inner function needs to be able to get the context (not provided by the criterion::block_on function).

Example

use criterion::{criterion_group, criterion_main, Criterion, BatchSize};
use commonware_runtime::{Clock, benchmarks::{context, tokio}};
use std::time::Duration;

fn my_benchmark(c: &mut Criterion) {
    let executor = tokio::Executor::default();
    c.bench_function("sleep_benchmark", |b| {
        b.to_async(&executor).iter_batched(|| (),
        |_| async {
            // Get the context
            let ctx = context::get::<commonware_runtime::tokio::Context>();
            // Use context features
            ctx.sleep(Duration::from_micros(10)).await;
        }, BatchSize::SmallInput);
    });
}

Bug

Fixes a small regression introduced by #735

TODO

  • Send bad payloads before echo payloads in consensus mocks (more interesting interactions should occur)
  • Use a Waker with root task (otherwise sleep will skip ahead too far): [runtime] Fix root waker #791

Comment thread runtime/src/benchmarking/criterion.rs Outdated
@patrick-ogrady patrick-ogrady added the bug Something isn't working label Apr 18, 2025
.filter_map(|x| self.notarizes[*x as usize].as_ref());

// Recover threshold signature
let proposal_signature = self
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Opted to remove this spawn code for now as data indicates there are much more efficient optimizations: #719

@patrick-ogrady patrick-ogrady modified the milestones: v0.0.45, Audit Ready Apr 18, 2025
Comment thread runtime/Cargo.toml Outdated
Comment thread runtime/src/benchmarking/criterion.rs Outdated
Comment thread runtime/src/benchmarking/criterion.rs Outdated
@patrick-ogrady patrick-ogrady changed the title [runtime] Support criterion::AsyncExecutor [runtime] Support criterion::AsyncExecutor + rayon::ThreadPool Apr 21, 2025
@patrick-ogrady patrick-ogrady marked this pull request as ready for review April 21, 2025 17:50
match msg {
Voter::Notarize(notarize) => {
// Notarize received digest
// Notarize random digest
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Generally speaking, sending random first should cause more issues (as the first message is the one that ends up getting persisted).

Comment thread consensus/src/threshold_simplex/mod.rs Outdated
/// b.to_async(&executor).iter_batched(|| (),
/// |_| async {
/// // Get the context
/// let ctx = context::get::<commonware_runtime::tokio::Context>();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Without control of the AsyncExecutor function interface, this is the best way IMHO to expose context to a benchmark (needed to setup storage, networking, etc.).

Comment thread runtime/src/deterministic.rs Outdated
Comment thread runtime/src/lib.rs
where
F: Future + Send + 'static,
F::Output: Send + 'static;
F: Future;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This aligns us with tokio's interface

Comment thread runtime/src/utils.rs
///
/// # Returns
/// A `Result` containing the configured [rayon::ThreadPool] or a [rayon::ThreadPoolBuildError] if the pool cannot be built.
pub fn create_pool<S: Spawner + Metrics>(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is an unrelated change but needed for some of the cryptography cleanup work.

BrendanChou
BrendanChou previously approved these changes Apr 21, 2025
Copy link
Copy Markdown
Collaborator

@BrendanChou BrendanChou left a comment

Choose a reason for hiding this comment

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

Consensus stuff LGTM (less familiar with runtime)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR integrates support for criterion’s AsyncExecutor and rayon’s ThreadPool while addressing a regression from #735, along with several refactorings and updates in test logic throughout the runtime and consensus modules.

  • Introduces a new helper function (create_pool) to create a rayon thread pool from a Spawner context.
  • Removes unnecessary Send + 'static bounds from future trait constraints to enable more flexible async functionality.
  • Adjusts consensus test behaviors and refactors task management in both deterministic and simplex runtime implementations.

Reviewed Changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
runtime/src/utils.rs Added a helper to create a rayon-compatible thread pool and updated use statements.
runtime/src/tokio/runtime.rs Removed Send constraints from futures to support more flexible execution.
runtime/src/deterministic.rs Refactored task and queue management with new Tasks struct implementations.
runtime/src/benchmarks/* Added a criterion-compatible executor for tokio.
consensus/src/** Updated logic in tests and mocks to adjust consensus message handling and signature recovery.
Comments suppressed due to low confidence (1)

consensus/src/threshold_simplex/actors/voter/actor.rs:363

  • [nitpick] The variable used for the filtered iterator of notarizes is named ambiguously. Consider renaming it (for example, to filtered_notarizes) to improve clarity in the threshold signature recovery logic.
.filter_map(|x| self.notarizes[*x as usize].as_ref());

Comment thread consensus/src/threshold_simplex/actors/voter/actor.rs
let result = executor.start(future);

// Clean up
context::clear();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is recommended to use iter_custom to cleanup anything the runtime did (like storage) rather than using the executor to do so.

}),
);
// Pin root task to the heap
let mut root = Box::pin(f);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This change created the most complexity.

Now that f is neither Send nor 'static, we need to be a lot more careful about where it can be stored.

Comment thread consensus/src/threshold_simplex/mod.rs Outdated
@patrick-ogrady patrick-ogrady merged commit 4c291da into main Apr 22, 2025
6 of 7 checks passed
@patrick-ogrady patrick-ogrady deleted the criterion-runtime branch April 22, 2025 00:10
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 22, 2025

Codecov Report

Attention: Patch coverage is 81.14754% with 46 lines in your changes missing coverage. Please review.

Project coverage is 89.39%. Comparing base (42f5f6c) to head (589e5e3).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
runtime/src/benchmarks/context.rs 0.00% 22 Missing ⚠️
runtime/src/benchmarks/tokio.rs 0.00% 19 Missing ⚠️
consensus/src/threshold_simplex/mod.rs 60.00% 4 Missing ⚠️
...sensus/src/threshold_simplex/actors/voter/actor.rs 97.72% 1 Missing ⚠️
@@            Coverage Diff             @@
##             main     #778      +/-   ##
==========================================
+ Coverage   89.37%   89.39%   +0.01%     
==========================================
  Files         165      166       +1     
  Lines       41307    41136     -171     
==========================================
- Hits        36917    36772     -145     
+ Misses       4390     4364      -26     
Files with missing lines Coverage Δ
consensus/src/simplex/mocks/conflicter.rs 95.18% <100.00%> (-0.12%) ⬇️
consensus/src/simplex/mocks/outdated.rs 94.36% <100.00%> (ø)
...onsensus/src/threshold_simplex/mocks/conflicter.rs 92.30% <100.00%> (-0.55%) ⬇️
runtime/src/deterministic.rs 99.32% <100.00%> (+<0.01%) ⬆️
runtime/src/lib.rs 97.26% <ø> (ø)
runtime/src/tokio/runtime.rs 94.94% <100.00%> (-0.02%) ⬇️
runtime/src/utils.rs 96.90% <100.00%> (+0.50%) ⬆️
...sensus/src/threshold_simplex/actors/voter/actor.rs 92.29% <97.72%> (-1.10%) ⬇️
consensus/src/threshold_simplex/mod.rs 98.26% <60.00%> (-0.06%) ⬇️
runtime/src/benchmarks/tokio.rs 0.00% <0.00%> (ø)
... and 1 more

... and 25 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 42f5f6c...589e5e3. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants