subetha-sidecar
You probably want the
subethaumbrella crate instead. It pulls insubetha-sidecaralong with both primitive families and re-exports the sidecar undersubetha::sidecar. Reach forsubetha-sidecardirectly only when you are writing a third-party primitive that needs the control plane without the rest of the workspace.
The control plane for the SubEtha
adaptive primitives library. One background thread per detected
NUMA node drains every registered instance's observation ring,
folds the observations into per-instance InstanceStats, and
asks each instance's Policy whether to migrate the strategy.
What it ships
-
Sidecar. The process-wide singleton, accessed viaglobal() -> Arc<Sidecar>. Pool of oneNodeSidecarper detected NUMA node, each with its own slot table and scan thread. -
SidecarBox<T: AdaptiveInstance>. RAII wrapper that registers the primitive on construction and unregisters on drop. Drop order is load-bearing:handledrops first (blocks on any in-flight scan), theninner: Box<T>drops, so the scan thread never sees freed memory. -
AdaptiveInstancetrait. The contract a primitive satisfies to be registered:header(),ring(),make_policy(), optionalapply_migration(new_tag). -
Policytrait. The decision function the sidecar calls per scan iteration:decide(&InstanceStats, current_tag) -> Option<u32>. Ships withFixedPolicy(u32)andNoMigrationPolicybuilt in. -
InstanceStats. The drain-and-fold accumulator the sidecar maintains per registered instance. Fields:ops_observed,total_latency_ticks,contention_ops,op_kind_counts: [u64; 8],last_seen_us_ago,migrations_triggered, plus a per-op-kind distinct-thread cache for multi-producer detection.
Capacity constants
| Constant | Value | Meaning |
|---|---|---|
N_OP_KINDS |
8 | per-primitive op-kind enum size; index 0 reserved for "unspecified" |
MAX_TRACKED_THREADS_PER_KIND |
4 | cardinality cache size; counts saturate at MAX + 1 |
DEFAULT_MAX_INSTANCES |
10,000 | hard cap on simultaneously-registered instances |
POLL_INTERVAL |
200 us | scan thread sleep between iterations |
NODE_ID_BITS |
8 | upper bits of InstanceId reserved for NUMA node index |
The instance cap is configurable via Sidecar::set_max_instances.
The rest are fixed by design. See the
tune-sidecar how-to
for the rationale behind each constant.
Quick start
use ;
use ;
// Construct + register in one call. Drop unregisters.
let prim = new;
let stats: = prim.stats;
For composing primitives via SidecarBox, including the
Arc<SidecarBox<T>> cross-thread pattern and the
register_raw escape hatch, see
Compose primitives via SidecarBox.
Requirements
SubEtha builds on stable Rust (edition 2024, MSRV 1.96). The
rust-toolchain.toml at the workspace root pins the stable channel;
downstream projects need only a recent stable toolchain.
Where it sits
your code
-> subetha / subetha-pointers (the two primitive families)
-> subetha-sidecar (this crate; control plane)
-> subetha-core (substrate)
Documentation
Full reference at the published wiki: https://variably-constant.github.io/SubEtha/docs/reference/subetha-sidecar/.
License
MIT. See LICENSE-MIT.