From 8c7bb2d2508473fc83c7d6692699ce913a550ed9 Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Tue, 14 Apr 2026 13:38:37 -0400 Subject: [PATCH 1/8] fix(registry): add large-thread-count feature to raise slab MAX_THREADS Adds a `large-thread-count` feature (off by default) that raises the sharded-slab MAX_THREADS limit from 4 096 to 131 072. This prevents tracing_subscriber from panicking on high-core nodes where large numbers of native threads are spawned (e.g. by the Ditto SDK in load-gen pods). When the feature is disabled the upstream default of 4 096 is used via the Config trait's default impl, so there is no behaviour change for existing consumers. Co-Authored-By: Claude Sonnet 4.6 --- tracing-subscriber/Cargo.toml | 3 +++ tracing-subscriber/src/registry/sharded.rs | 24 ++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index 807880b8cd..5822ddd922 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -31,6 +31,9 @@ env-filter = ["matchers", "regex", "once_cell", "tracing", "std", "thread_local" fmt = ["registry", "std"] ansi = ["fmt", "nu-ansi-term"] registry = ["sharded-slab", "thread_local", "std"] +# Raises the sharded-slab MAX_THREADS limit from 4 096 to 131 072. +# Enable on high-core nodes where many native threads are spawned. +large-thread-count = [] json = ["tracing-serde", "serde", "serde_json"] valuable = ["tracing-core/valuable", "valuable_crate", "valuable-serde", "tracing-serde/valuable"] # Enables support for local time when using the `time` crate timestamp diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index 544a5dc344..812c823c31 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -1,4 +1,20 @@ -use sharded_slab::{pool::Ref, Clear, Pool}; +use sharded_slab::{pool::Ref, Clear, Config, Pool}; + +/// Custom [`sharded_slab::Config`] for the span registry pool. +/// +/// When the `large-thread-count` feature is enabled, `MAX_THREADS` is raised +/// from the upstream default of 4 096 to 131 072, preventing panics on +/// high-core machines where large numbers of native threads are spawned. +/// When the feature is disabled the trait default (4 096) is used unchanged. +#[derive(Debug)] +struct SlabConfig; + +impl Config for SlabConfig { + /// 131 072 threads = 2^17. Only active with the `large-thread-count` + /// feature; otherwise falls back to the trait default of 4 096. + #[cfg(feature = "large-thread-count")] + const MAX_THREADS: usize = 131_072; +} use thread_local::ThreadLocal; use super::stack::SpanStack; @@ -90,7 +106,7 @@ use tracing_core::{ #[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))] #[derive(Debug)] pub struct Registry { - spans: Pool, + spans: Pool, current_spans: ThreadLocal>, next_filter_id: u8, } @@ -109,7 +125,7 @@ pub struct Registry { #[derive(Debug)] pub struct Data<'a> { /// Immutable reference to the pooled `DataInner` entry. - inner: Ref<'a, DataInner>, + inner: Ref<'a, DataInner, SlabConfig>, } /// Stored data associated with a span. @@ -180,7 +196,7 @@ pub(crate) struct CloseGuard<'a> { } impl Registry { - fn get(&self, id: &Id) -> Option> { + fn get(&self, id: &Id) -> Option> { self.spans.get(id_to_idx(id)) } From 19c1fd9107aefa19f2391b54c1a24d250a16d088 Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Tue, 14 Apr 2026 13:52:44 -0400 Subject: [PATCH 2/8] test(registry): assert SlabConfig MAX_THREADS when large-thread-count enabled Co-Authored-By: Claude Sonnet 4.6 --- tracing-subscriber/src/registry/sharded.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index 812c823c31..252b297c86 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -921,4 +921,13 @@ mod tests { state.assert_closed_in_order(["child", "parent", "grandparent"]); }); } + + #[cfg(feature = "large-thread-count")] + #[test] + fn large_thread_count_raises_max_threads() { + assert_eq!(SlabConfig::MAX_THREADS, 131_072); + // Confirm the registry pool is parameterised on SlabConfig at the type + // level — this is a compile-time check dressed as a runtime test. + let _: &Pool = &Pool::new(); + } } From 2f485256d785a4e4007c7c45da616b3057cf2824 Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Tue, 14 Apr 2026 13:55:49 -0400 Subject: [PATCH 3/8] fix(registry): use Pool::new_with_config for SlabConfig; fix test Pool init Co-Authored-By: Claude Sonnet 4.6 --- tracing-subscriber/src/registry/sharded.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index 252b297c86..14549ee19c 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -151,7 +151,7 @@ struct DataInner { impl Default for Registry { fn default() -> Self { Self { - spans: Pool::new(), + spans: Pool::new_with_config::(), current_spans: ThreadLocal::new(), next_filter_id: 0, } @@ -928,6 +928,6 @@ mod tests { assert_eq!(SlabConfig::MAX_THREADS, 131_072); // Confirm the registry pool is parameterised on SlabConfig at the type // level — this is a compile-time check dressed as a runtime test. - let _: &Pool = &Pool::new(); + let _: &Pool = &Pool::new_with_config::(); } } From 52b69c0d3faf5a33c07f972ed5ee40d077c19839 Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Wed, 15 Apr 2026 09:08:37 -0400 Subject: [PATCH 4/8] fix(registry): make higher MAX_THREADS unconditional, remove feature gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The large-thread-count Cargo feature caused complex activation problems across multiple workspace boundaries in the Ditto monorepo. Since this fork is always used with Ditto builds, raise MAX_THREADS = 131_072 unconditionally — no feature flag required. Co-Authored-By: Claude Sonnet 4.6 --- tracing-subscriber/Cargo.toml | 3 --- tracing-subscriber/src/registry/sharded.rs | 15 ++++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index 5822ddd922..807880b8cd 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -31,9 +31,6 @@ env-filter = ["matchers", "regex", "once_cell", "tracing", "std", "thread_local" fmt = ["registry", "std"] ansi = ["fmt", "nu-ansi-term"] registry = ["sharded-slab", "thread_local", "std"] -# Raises the sharded-slab MAX_THREADS limit from 4 096 to 131 072. -# Enable on high-core nodes where many native threads are spawned. -large-thread-count = [] json = ["tracing-serde", "serde", "serde_json"] valuable = ["tracing-core/valuable", "valuable_crate", "valuable-serde", "tracing-serde/valuable"] # Enables support for local time when using the `time` crate timestamp diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index 14549ee19c..939bd492de 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -2,17 +2,15 @@ use sharded_slab::{pool::Ref, Clear, Config, Pool}; /// Custom [`sharded_slab::Config`] for the span registry pool. /// -/// When the `large-thread-count` feature is enabled, `MAX_THREADS` is raised -/// from the upstream default of 4 096 to 131 072, preventing panics on -/// high-core machines where large numbers of native threads are spawned. -/// When the feature is disabled the trait default (4 096) is used unchanged. +/// Raises `MAX_THREADS` from the upstream default of 4 096 to 131 072, +/// preventing panics on high-core machines (e.g. HyDRA load-gen nodes) where +/// large numbers of native threads are spawned. #[derive(Debug)] struct SlabConfig; impl Config for SlabConfig { - /// 131 072 threads = 2^17. Only active with the `large-thread-count` - /// feature; otherwise falls back to the trait default of 4 096. - #[cfg(feature = "large-thread-count")] + /// 131 072 threads = 2^17. Raised from the upstream default of 4 096 to + /// prevent `sharded_slab` panics on high-core machines. const MAX_THREADS: usize = 131_072; } use thread_local::ThreadLocal; @@ -922,9 +920,8 @@ mod tests { }); } - #[cfg(feature = "large-thread-count")] #[test] - fn large_thread_count_raises_max_threads() { + fn slab_config_raises_max_threads() { assert_eq!(SlabConfig::MAX_THREADS, 131_072); // Confirm the registry pool is parameterised on SlabConfig at the type // level — this is a compile-time check dressed as a runtime test. From bde763367722984f02b52c8e0df4f90e91712b87 Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Wed, 15 Apr 2026 13:45:06 -0400 Subject: [PATCH 5/8] fix(registry): restore large-thread-count feature gate for MAX_THREADS Make MAX_THREADS = 131_072 conditional on the `large-thread-count` feature flag rather than unconditional. The feature was previously removed to work around a cross-workspace patch issue in the ditto monorepo (now fixed by updating .cargo/config.toml patches). Co-Authored-By: Claude Sonnet 4.6 --- tracing-subscriber/Cargo.toml | 3 +++ tracing-subscriber/src/registry/sharded.rs | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tracing-subscriber/Cargo.toml b/tracing-subscriber/Cargo.toml index 807880b8cd..932c6aaebe 100644 --- a/tracing-subscriber/Cargo.toml +++ b/tracing-subscriber/Cargo.toml @@ -31,6 +31,9 @@ env-filter = ["matchers", "regex", "once_cell", "tracing", "std", "thread_local" fmt = ["registry", "std"] ansi = ["fmt", "nu-ansi-term"] registry = ["sharded-slab", "thread_local", "std"] +# Raises the sharded-slab MAX_THREADS from 4 096 to 131 072, preventing panics +# on high-core machines where large numbers of native threads are spawned. +large-thread-count = [] json = ["tracing-serde", "serde", "serde_json"] valuable = ["tracing-core/valuable", "valuable_crate", "valuable-serde", "tracing-serde/valuable"] # Enables support for local time when using the `time` crate timestamp diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index 939bd492de..76461362fa 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -2,15 +2,17 @@ use sharded_slab::{pool::Ref, Clear, Config, Pool}; /// Custom [`sharded_slab::Config`] for the span registry pool. /// -/// Raises `MAX_THREADS` from the upstream default of 4 096 to 131 072, -/// preventing panics on high-core machines (e.g. HyDRA load-gen nodes) where -/// large numbers of native threads are spawned. +/// When the `large-thread-count` feature is enabled, `MAX_THREADS` is raised +/// from the upstream default of 4 096 to 131 072, preventing panics on +/// high-core machines (e.g. HyDRA load-gen nodes) where large numbers of +/// native threads are spawned. #[derive(Debug)] struct SlabConfig; impl Config for SlabConfig { - /// 131 072 threads = 2^17. Raised from the upstream default of 4 096 to - /// prevent `sharded_slab` panics on high-core machines. + /// When the `large-thread-count` feature is enabled: 131 072 threads = 2^17. + /// Otherwise falls back to the `sharded_slab` default of 4 096. + #[cfg(feature = "large-thread-count")] const MAX_THREADS: usize = 131_072; } use thread_local::ThreadLocal; @@ -921,6 +923,7 @@ mod tests { } #[test] + #[cfg(feature = "large-thread-count")] fn slab_config_raises_max_threads() { assert_eq!(SlabConfig::MAX_THREADS, 131_072); // Confirm the registry pool is parameterised on SlabConfig at the type From 82f7735895a9bba59fd4eb3291cb8cc834f5346b Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Thu, 16 Apr 2026 10:15:56 -0400 Subject: [PATCH 6/8] fix(registry): restrict large-thread-count MAX_THREADS to 64-bit targets On 32-bit targets (e.g. wasm32-unknown-unknown), MAX_THREADS = 131 072 requires 17 bits for thread IDs, which exhausts sharded-slab's bit-packing budget (total usize width = 32 bits) and causes a compile-time overflow in slot::Generation::LEN. Guard the raised constant behind `target_pointer_width = "64"` so wasm32 and other 32-bit targets fall back to the sharded-slab default of 4 096. Co-Authored-By: Claude Sonnet 4.6 --- tracing-subscriber/src/registry/sharded.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index 76461362fa..3c439769d1 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -10,9 +10,11 @@ use sharded_slab::{pool::Ref, Clear, Config, Pool}; struct SlabConfig; impl Config for SlabConfig { - /// When the `large-thread-count` feature is enabled: 131 072 threads = 2^17. - /// Otherwise falls back to the `sharded_slab` default of 4 096. - #[cfg(feature = "large-thread-count")] + /// When the `large-thread-count` feature is enabled on a 64-bit target: + /// 131 072 threads = 2^17. On 32-bit targets (e.g. wasm32) the raised value + /// would overflow `sharded_slab`'s bit-packing arithmetic, so the default + /// of 4 096 is retained there regardless of the feature flag. + #[cfg(all(feature = "large-thread-count", target_pointer_width = "64"))] const MAX_THREADS: usize = 131_072; } use thread_local::ThreadLocal; @@ -923,7 +925,7 @@ mod tests { } #[test] - #[cfg(feature = "large-thread-count")] + #[cfg(all(feature = "large-thread-count", target_pointer_width = "64"))] fn slab_config_raises_max_threads() { assert_eq!(SlabConfig::MAX_THREADS, 131_072); // Confirm the registry pool is parameterised on SlabConfig at the type From f7ef9e1b0c58c7bd552ed015665561ba7c52e655 Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Fri, 17 Apr 2026 14:00:22 -0400 Subject: [PATCH 7/8] fix(registry): move SlabConfig after imports --- tracing-subscriber/src/registry/sharded.rs | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index 3c439769d1..c35b281b79 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -1,22 +1,4 @@ use sharded_slab::{pool::Ref, Clear, Config, Pool}; - -/// Custom [`sharded_slab::Config`] for the span registry pool. -/// -/// When the `large-thread-count` feature is enabled, `MAX_THREADS` is raised -/// from the upstream default of 4 096 to 131 072, preventing panics on -/// high-core machines (e.g. HyDRA load-gen nodes) where large numbers of -/// native threads are spawned. -#[derive(Debug)] -struct SlabConfig; - -impl Config for SlabConfig { - /// When the `large-thread-count` feature is enabled on a 64-bit target: - /// 131 072 threads = 2^17. On 32-bit targets (e.g. wasm32) the raised value - /// would overflow `sharded_slab`'s bit-packing arithmetic, so the default - /// of 4 096 is retained there regardless of the feature flag. - #[cfg(all(feature = "large-thread-count", target_pointer_width = "64"))] - const MAX_THREADS: usize = 131_072; -} use thread_local::ThreadLocal; use super::stack::SpanStack; @@ -38,6 +20,24 @@ use tracing_core::{ Event, Interest, Metadata, Subscriber, }; +/// Custom [`sharded_slab::Config`] for the span registry pool. +/// +/// When the `large-thread-count` feature is enabled, `MAX_THREADS` is raised +/// from the upstream default of 4 096 to 131 072, preventing panics on +/// high-core machines (e.g. HyDRA load-gen nodes) where large numbers of +/// native threads are spawned. +#[derive(Debug)] +struct SlabConfig; + +impl Config for SlabConfig { + /// When the `large-thread-count` feature is enabled on a 64-bit target: + /// 131 072 threads = 2^17. On 32-bit targets (e.g. wasm32) the raised value + /// would overflow `sharded_slab`'s bit-packing arithmetic, so the default + /// of 4 096 is retained there regardless of the feature flag. + #[cfg(all(feature = "large-thread-count", target_pointer_width = "64"))] + const MAX_THREADS: usize = 131_072; +} + /// A shared, reusable store for spans. /// /// A `Registry` is a [`Subscriber`] around which multiple [`Layer`]s From 9474165a817d5fb76d6369efcbd8f3248bc6c213 Mon Sep 17 00:00:00 2001 From: mc-ditto Date: Fri, 17 Apr 2026 14:03:38 -0400 Subject: [PATCH 8/8] fix(registry): assert Registry.spans type in slab_config test --- tracing-subscriber/src/registry/sharded.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tracing-subscriber/src/registry/sharded.rs b/tracing-subscriber/src/registry/sharded.rs index c35b281b79..2c2c82e36e 100644 --- a/tracing-subscriber/src/registry/sharded.rs +++ b/tracing-subscriber/src/registry/sharded.rs @@ -928,8 +928,10 @@ mod tests { #[cfg(all(feature = "large-thread-count", target_pointer_width = "64"))] fn slab_config_raises_max_threads() { assert_eq!(SlabConfig::MAX_THREADS, 131_072); - // Confirm the registry pool is parameterised on SlabConfig at the type - // level — this is a compile-time check dressed as a runtime test. - let _: &Pool = &Pool::new_with_config::(); + // Confirm the Registry pool is actually parameterised on SlabConfig — + // this is a compile-time check: if `Registry::spans` ever changes to a + // different Config type, the type annotation below will fail to compile. + let registry = Registry::default(); + let _: &Pool = ®istry.spans; } }