Skip to content

feat(thread_aware): expose ThreadRegistry::with_hardware for SystemHardware injection#535

Open
sandersaares wants to merge 7 commits into
mainfrom
u/sasaares/threadregistry-public-hardware
Open

feat(thread_aware): expose ThreadRegistry::with_hardware for SystemHardware injection#535
sandersaares wants to merge 7 commits into
mainfrom
u/sasaares/threadregistry-public-hardware

Conversation

@sandersaares

@sandersaares sandersaares commented Jun 29, 2026

Copy link
Copy Markdown
Member

Promote ThreadRegistry::with_hardware to public API so consumers can inject a single shared many_cpus::SystemHardware instance instead of having every layer re-resolve SystemHardware::current(). SystemHardware is meant to be reused as a service, but the only public constructor (new / default) hid the injection path, leaving customers unable to supply their own.

ThreadRegistry::new keeps resolving SystemHardware::current() at the top of the chain and threads that one instance through, so simple call sites are unchanged. Added many_cpus::SystemHardware to the crate's allowed_external_types allowlist since it now appears in the public signature.

Also fixes a pre-existing boundary off-by-one: the asserts now permit exactly u16::MAX processors/memory regions, matching the documented 'more than u16::MAX' panic boundary. And the 'not enough processors available' panic now reports the requested vs available counts to make injection failures actionable.

This is the only place in the workspace that touches SystemHardware; no other crate constructs ThreadRegistry.

Promote with_hardware to public API so services can inject a single shared SystemHardware instance rather than re-resolving SystemHardware::current(). new() stays a convenience wrapper threading the resolved instance through. Allow many_cpus::SystemHardware in external types.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sandersaares sandersaares force-pushed the u/sasaares/threadregistry-public-hardware branch from f07843f to f36f030 Compare June 29, 2026 09:30
@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.0%. Comparing base (542a32c) to head (e2623e1).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #535   +/-   ##
=======================================
  Coverage   100.0%   100.0%           
=======================================
  Files         343      343           
  Lines       26202    26208    +6     
=======================================
+ Hits        26202    26208    +6     

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

@sandersaares sandersaares marked this pull request as ready for review June 29, 2026 11:06
Copilot AI review requested due to automatic review settings June 29, 2026 11:06

Copilot AI left a comment

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.

Pull request overview

This PR makes ThreadRegistry::with_hardware a public API (behind the threads feature) so downstream consumers can inject and reuse a shared many_cpus::SystemHardware instead of repeatedly resolving SystemHardware::current() across layers.

Changes:

  • Promotes ThreadRegistry::with_hardware from pub(crate) to pub and updates rustdoc to describe intended injection/reuse.
  • Keeps ThreadRegistry::new behavior as a convenience wrapper that resolves SystemHardware::current().
  • Adds many_cpus_impl::system_hardware::SystemHardware to cargo_check_external_types allowlist to account for the new public signature.

Reviewed changes

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

File Description
crates/thread_aware/src/registry.rs Exposes with_hardware publicly and adjusts docs for new/with_hardware.
crates/thread_aware/Cargo.toml Allowlists SystemHardware’s defining path for public API external-type checks.
Comments suppressed due to low confidence (2)

crates/thread_aware/src/registry.rs:64

  • The panic documentation says "more than u16::MAX processors or memory regions", but with_hardware currently asserts processors.len() < u16::MAX as usize and numa_nodes.len() < u16::MAX as usize, which also panics when the count is exactly u16::MAX. Update the docs to match the actual boundary (or adjust the checks).
    /// This will panic if there are not enough processors available when using `Manual` or if no processors are available when using `Auto` or `All`.
    /// If there are more than `u16::MAX` processors or memory regions.

crates/thread_aware/src/registry.rs:88

  • Now that with_hardware is part of the public API, the panic message from this expect is customer-facing. It would be more actionable if it included the requested ProcessorCount value (e.g., which manual count was requested).
        let processors = match count {
            ProcessorCount::Auto | ProcessorCount::All => builder.take_all(),
            ProcessorCount::Manual(count) => builder.take(*count),
        }
        .expect("Not enough processors available");

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/thread_aware/src/registry.rs
sandersaares and others added 2 commits June 29, 2026 14:15
The assert rejected exactly u16::MAX, contradicting the documented 'more than u16::MAX' boundary; both fit in u16 so allow them. Use try_from per clippy.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 29, 2026 11:18

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread crates/thread_aware/src/registry.rs Outdated
Comment thread crates/thread_aware/src/registry.rs Outdated
…asserts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 29, 2026 11:28

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

sandersaares and others added 2 commits June 29, 2026 14:45
The u16::MAX processor/memory-region asserts can't be exercised via fake hardware (region count can never exceed processor count), so move them into a coverage(off) helper.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ip mutating unreachable guard

The coverage CI compiles the lib crate (not just tests) with coverage instrumentation, so the coverage_attribute feature must be gated on coverage_nightly alone, matching crates like bytesbuf that put coverage(off) on production code. Mark check_capacity mutants::skip since its asserts are unreachable via tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 29, 2026 14:01

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@Vaiz Vaiz left a comment

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.

Thing to consider: now that we expose a type from 3d party crate, it means any breaking change in many_cpus crate will be propagated as breaking change in thread_aware

Is there some other way to do it?

@sandersaares

sandersaares commented Jun 30, 2026

Copy link
Copy Markdown
Member Author

@Vaiz If you have specific proposals, please propose. Otherwise, this is not particularly new information and has already been considered. I was thinking it might be nice to split thread_aware into "the thread awareness part" and "the part that connects this with hardware" but it feels like a too big refactoring for now. Maybe something to file a future feature for? https://o365exchange.visualstudio.com/O365%20Core/_workitems/edit/7546921

@Vaiz

Vaiz commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

@Vaiz If you have specific proposals, please propose. Otherwise, this is not particularly new information and has already been considered. I was thinking it might be nice to split thread_aware into "the thread awareness part" and "the part that connects this with hardware" but it feels like a too big refactoring for now. Maybe something to file a future feature for? https://o365exchange.visualstudio.com/O365%20Core/_workitems/edit/7546921

thread_aware should remove any dependency on many_cpus and have its own SystemHardware struct that can be constructed by consumer crates. So somewhere outside of thread_aware crate there will be a conversion of many_cpus::SystemHardware to thread_aware::SystemHardware

pub(crate) fn with_hardware(count: &ProcessorCount, hardware: &SystemHardware) -> Self {
let builder = hardware.processors().to_builder();

pub fn with_hardware(count: &ProcessorCount, hardware: &SystemHardware) -> Self {

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.

yet another exposure to APIs that can change. thread_aware being such a foundational crate, I believe we should have a minimal "trait-only" crate that exposes bare minimum (ThreadAware trait, Affinity type) so libraries that expose these APIs can rely on stable crate.

@sandersaares

sandersaares commented Jun 30, 2026

Copy link
Copy Markdown
Member Author

thread_aware should remove any dependency on many_cpus and have its own SystemHardware struct that can be constructed by consumer crates. So somewhere outside of thread_aware crate there will be a conversion of many_cpus::SystemHardware to thread_aware::SystemHardware

Thanks for concrete suggestion! I am not going to go down this path because it would require reinventing the entire SystemHardware functionality - wrapping something behind another layer is not desirable cost/benefit. This exposure is not an accident or a byproduct - it is intentional. Just, ideally it would only be exposed to hosters of thread-aware types (runtime authors) and to advanced authors of thread-aware types (for testing) but not necessarily consumers of them. Today, we are not there yet but in the future we can be there (but not in scope of this PR).

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.

6 participants