Skip to content

Commit d935e8f

Browse files
committed
Clean up horus/ codebase: zero clippy warnings, consistent formatting
- Fix all clippy warnings across workspace (48 warnings → 0): - Remove unnecessary pointer cast in dispatch.rs - Add BackendMap type alias to reduce type complexity in registry.rs - Replace loop-index patterns with iterator enumerate in tests - Use .is_some() instead of if-let-Some(_) pattern - Collapse nested if-else into else-if chains - Replace manual range checks with .contains() - Remove redundant u64 casts where type already matches - Fix doc list indentation in benchmarks - Remove dead code in loom tests (identical if/else branches) - Suppress too_many_arguments for PyO3 bindings - Replace approximate PI value with non-PI test data - Run cargo fmt across all 72 files with formatting drift - Fix compilation errors: - Restore TopicMetadata re-export dropped from lib.rs - Add missing SchedulerConfig import in doctest - Delete unused driver.rs, examples, version.rs, yaml_utils.rs - Refactor scheduling: add blackbox/config/safety_monitor improvements - Update CI workflows, READMEs, Python bindings
1 parent 0f79046 commit d935e8f

File tree

113 files changed

+2275
-2708
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+2275
-2708
lines changed

.github/workflows/integration-tests.yml

Lines changed: 589 additions & 26 deletions
Large diffs are not rendered by default.

.github/workflows/multi-platform.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ on:
1616
env:
1717
CARGO_TERM_COLOR: always
1818
# Minimum Supported Rust Version
19-
# Requires 1.92.0+ due to horus_ai crate requirements
2019
MSRV: "1.92.0"
2120

2221
jobs:
@@ -180,7 +179,7 @@ jobs:
180179
runs-on: ubuntu-latest
181180
strategy:
182181
matrix:
183-
rust: ["1.92.0"] # MSRV - horus_ai requires 1.92.0
182+
rust: ["1.92.0"] # MSRV
184183
steps:
185184
- uses: actions/checkout@v4
186185

.github/workflows/release.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ jobs:
9595
uses: dtolnay/rust-toolchain@stable
9696

9797
# Publish crates in dependency order
98+
- name: Publish horus_types
99+
run: cargo publish -p horus_types --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
100+
continue-on-error: true
101+
102+
- name: Wait for crates.io
103+
run: sleep 30
104+
98105
- name: Publish horus_core
99106
run: cargo publish -p horus_core --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
100107
continue-on-error: true
@@ -116,13 +123,6 @@ jobs:
116123
- name: Wait for crates.io
117124
run: sleep 30
118125

119-
- name: Publish horus_ai
120-
run: cargo publish -p horus_ai --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
121-
continue-on-error: true
122-
123-
- name: Wait for crates.io
124-
run: sleep 30
125-
126126
- name: Publish horus
127127
run: cargo publish -p horus --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
128128
continue-on-error: true

.github/workflows/safety.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ on:
2121
# Only run on PRs that touch unsafe code
2222
- 'horus_core/src/memory/**'
2323
- 'horus_core/src/communication/**'
24-
- 'horus_core/src/ipc/**'
2524

2625
env:
2726
CARGO_TERM_COLOR: always
@@ -66,12 +65,6 @@ jobs:
6665
env:
6766
MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-permissive-provenance
6867

69-
- name: MIRI - horus_core ipc module
70-
run: |
71-
cargo miri test -p horus_core --lib -- ipc::
72-
env:
73-
MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-permissive-provenance
74-
7568
# Run MIRI on horus_library Pod types (landmark, tracking, detection_pod, etc.)
7669
- name: MIRI - horus_library Pod types
7770
run: |

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,8 @@ horus/
230230
├── horus_core/ # Core framework (Node, Topic, Scheduler)
231231
├── horus_macros/ # Procedural macros (node!, message!)
232232
├── horus_library/ # Standard message types and HFrame transforms
233+
├── horus_types/ # Core type definitions (descriptors, encodings, tensors)
233234
├── horus_manager/ # CLI tool (horus command)
234-
├── horus_ai/ # ML model registry
235235
├── horus_py/ # Python bindings
236236
├── benchmarks/ # Performance benchmarks
237237
└── tests/ # Integration tests

README.md

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ message!(MotorCommand = (f64,)); // voltage
5050

5151
node! {
5252
SensorNode {
53-
pub { reading: SensorReading -> "sensor/data" }
53+
pub { reading: SensorReading -> "sensor.data" }
5454
data { position: f64 = 0.0 }
5555

5656
tick {
@@ -62,8 +62,8 @@ node! {
6262

6363
node! {
6464
ControllerNode {
65-
sub { sensor: SensorReading -> "sensor/data" }
66-
pub { command: MotorCommand -> "motor/cmd" }
65+
sub { sensor: SensorReading -> "sensor.data" }
66+
pub { command: MotorCommand -> "motor.cmd" }
6767
data { target: f64 = 1.0 }
6868

6969
tick {
@@ -125,24 +125,14 @@ Nodes communicate through topics. The framework automatically picks the fastest
125125
```rust
126126
use horus::prelude::*;
127127

128-
let topic: Topic<f64> = Topic::new("sensor_data", None)?;
128+
let topic: Topic<f64> = Topic::new("sensor_data")?;
129129

130130
topic.send(42.0);
131131
if let Some(value) = topic.recv() {
132132
println!("Got: {}", value);
133133
}
134134
```
135135

136-
For multi-machine setups, just add an address:
137-
138-
```rust
139-
// Same-machine: shared memory (sub-microsecond)
140-
let local: Topic<f64> = Topic::new("sensors", None)?;
141-
142-
// Cross-machine: network (microseconds)
143-
let remote: Topic<f64> = Topic::new("sensors@192.168.1.100:8000", None)?;
144-
```
145-
146136
### Custom Nodes
147137

148138
Define nodes with the `node!` macro:
@@ -154,8 +144,8 @@ message!(SensorData = (f64, u32));
154144

155145
node! {
156146
MyNode {
157-
pub { output: SensorData -> "sensor/output" }
158-
sub { input: SensorData -> "sensor/input" }
147+
pub { output: SensorData -> "sensor.output" }
148+
sub { input: SensorData -> "sensor.input" }
159149
data { counter: u32 = 0 }
160150

161151
tick {
@@ -184,7 +174,7 @@ HORUS includes standard robotics message types:
184174
```rust
185175
use horus::prelude::*;
186176

187-
let cmd_topic: Topic<CmdVel> = Topic::new("cmd_vel", None)?;
177+
let cmd_topic: Topic<CmdVel> = Topic::new("cmd_vel")?;
188178
cmd_topic.send(CmdVel::new(1.0, 0.0));
189179
```
190180

@@ -219,7 +209,6 @@ horus topic list # See active topics
219209
horus node list # See running nodes
220210
horus pkg install <name> # Install packages
221211
horus deploy <target> # Deploy to robot
222-
horus sim # Launch simulator
223212
```
224213

225214
Run `horus --help` for all commands.

benchmarks/src/bin/all_paths_latency.rs

Lines changed: 34 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ use horus_benchmarks::platform::{detect_platform, has_constant_tsc, PlatformInfo
4545
use horus_benchmarks::set_cpu_affinity;
4646
use horus_benchmarks::stats::Statistics;
4747
use horus_benchmarks::timing::{rdtsc, rdtscp, serialize, PrecisionTimer, RdtscCalibration};
48-
use horus_benchmarks::{
49-
BenchmarkConfig, BenchmarkResult, DeterminismMetrics, ThroughputMetrics,
50-
};
48+
use horus_benchmarks::{BenchmarkConfig, BenchmarkResult, DeterminismMetrics, ThroughputMetrics};
5149
use horus_library::messages::cmd_vel::CmdVel;
5250
use std::hint::spin_loop;
5351
use std::process::{Command, Stdio};
@@ -69,6 +67,7 @@ const TIMEOUT: Duration = Duration::from_secs(30);
6967
/// 1. Setup (spawn consumer, wait for topology, trigger migration) takes ~350ms
7068
/// 2. At ~100ns/msg SHM speed, 105K msgs finishes in ~10ms
7169
/// 3. Publishers must still be running during the measurement phase
70+
///
7271
/// 10M msgs × ~100ns = ~1s — enough headroom for setup + warmup + measurement.
7372
const PODSHM_MSGS_PER_PUB: u64 = 10_000_000;
7473

@@ -143,7 +142,12 @@ fn main() {
143142
// --- Child process entry points ---
144143
if args.len() >= 5 && args[1] == "--child-publisher" {
145144
let paced = args.get(5).map(|s| s == "--paced").unwrap_or(false);
146-
run_child_publisher(&args[2], args[3].parse().unwrap(), args[4].parse().unwrap(), paced);
145+
run_child_publisher(
146+
&args[2],
147+
args[3].parse().unwrap(),
148+
args[4].parse().unwrap(),
149+
paced,
150+
);
147151
return;
148152
}
149153
if args.len() >= 5 && args[1] == "--child-consumer" {
@@ -174,11 +178,7 @@ fn main() {
174178
let mut results: Vec<ScenarioResult> = Vec::new();
175179

176180
// === Intra-process (5 scenarios) ===
177-
println!(
178-
"{} Intra-Process {}",
179-
"───",
180-
"─".repeat(BOX_W - 19)
181-
);
181+
println!("─── Intra-Process {}", "─".repeat(BOX_W - 19));
182182
println!();
183183

184184
let r = bench_direct_channel(&timer);
@@ -203,8 +203,7 @@ fn main() {
203203

204204
// === Cross-process (4 scenarios) ===
205205
println!(
206-
"{} Cross-Process (RDTSC-in-payload) {}",
207-
"───",
206+
"─── Cross-Process (RDTSC-in-payload) {}",
208207
"─".repeat(BOX_W - 37)
209208
);
210209
println!();
@@ -229,8 +228,7 @@ fn main() {
229228
// === Raw atomic probe (hardware floor) ===
230229
println!();
231230
println!(
232-
"{} Hardware Floor (raw SHM atomic) {}",
233-
"───",
231+
"─── Hardware Floor (raw SHM atomic) {}",
234232
"─".repeat(BOX_W - 38)
235233
);
236234
println!();
@@ -243,8 +241,7 @@ fn main() {
243241
if !skip_stress {
244242
println!();
245243
println!(
246-
"{} Scalability Stress (PodShm N-pub x M-sub) {}",
247-
"───",
244+
"─── Scalability Stress (PodShm N-pub x M-sub) {}",
248245
"─".repeat(BOX_W - 47)
249246
);
250247
println!();
@@ -290,10 +287,7 @@ fn print_header(platform: &PlatformInfo, cal: &RdtscCalibration) {
290287
println!();
291288
println!("{}", box_top());
292289
println!("{}", box_center("HORUS IPC Latency Benchmark v2.0"));
293-
println!(
294-
"{}",
295-
box_center("Per-Message RDTSC-Instrumented Latency")
296-
);
290+
println!("{}", box_center("Per-Message RDTSC-Instrumented Latency"));
297291
println!("{}", box_sep());
298292

299293
let model = truncate(&platform.cpu.model, BOX_W - 8);
@@ -1176,7 +1170,10 @@ fn wait_for_topology(topic: &Topic<CmdVel>, min_pubs: u32, min_subs: u32, timeou
11761170
if Instant::now() > deadline {
11771171
eprintln!(
11781172
" [warn] topology timeout: wanted pubs>={} subs>={}, got pubs={} subs={}",
1179-
min_pubs, min_subs, topic.pub_count(), topic.sub_count()
1173+
min_pubs,
1174+
min_subs,
1175+
topic.pub_count(),
1176+
topic.sub_count()
11801177
);
11811178
break;
11821179
}
@@ -1274,7 +1271,9 @@ fn collect_cross_proc(
12741271
if let Some(msg) = consumer.recv() {
12751272
let recv_cycles = rdtscp();
12761273
let send_cycles = msg.stamp_nanos;
1277-
let delta = recv_cycles.wrapping_sub(send_cycles).saturating_sub(overhead);
1274+
let delta = recv_cycles
1275+
.wrapping_sub(send_cycles)
1276+
.saturating_sub(overhead);
12781277
latencies.push(cal.cycles_to_ns(delta));
12791278
total += 1;
12801279
last_recv_cycles = recv_cycles;
@@ -1357,7 +1356,9 @@ fn collect_pod_shm(
13571356
if let Some(msg) = consumer.recv() {
13581357
let recv_cycles = rdtscp();
13591358
let send_cycles = msg.stamp_nanos;
1360-
let delta = recv_cycles.wrapping_sub(send_cycles).saturating_sub(overhead);
1359+
let delta = recv_cycles
1360+
.wrapping_sub(send_cycles)
1361+
.saturating_sub(overhead);
13611362
latencies.push(cal.cycles_to_ns(delta));
13621363
total += 1;
13631364
last_recv_cycles = recv_cycles;
@@ -1742,10 +1743,7 @@ fn print_detail(r: &ScenarioResult) {
17421743

17431744
if r.latencies_ns.is_empty() {
17441745
println!(" NO SAMPLES -- topology did not route messages to parent consumer");
1745-
println!(
1746-
" Messages: {}/{} received",
1747-
r.total_received, r.total_sent
1748-
);
1746+
println!(" Messages: {}/{} received", r.total_received, r.total_sent);
17491747
println!();
17501748
return;
17511749
}
@@ -1817,10 +1815,7 @@ fn print_pod_shm_detail(r: &ScenarioResult) {
18171815
let fresh_stats = Statistics::from_samples(freshness, 95.0, false);
18181816
println!(
18191817
" Freshness (msgs between reads): p50: {} p95: {} p99: {} max: {}",
1820-
fresh_stats.median as u64,
1821-
fresh_stats.p95,
1822-
fresh_stats.p99,
1823-
fresh_stats.max,
1818+
fresh_stats.median as u64, fresh_stats.p95, fresh_stats.p99, fresh_stats.max,
18241819
);
18251820
}
18261821
}
@@ -1853,8 +1848,8 @@ fn print_summary(results: &[ScenarioResult]) {
18531848
let w = BOX_W + 4;
18541849
println!("{}", "=".repeat(w));
18551850
println!(
1856-
" {:<18} {:>7} {:>8} {:>8} {:>8} {:>8} {:>8} {}",
1857-
"Scenario", "Type", "p50", "p95", "p99", "p99.9", "max", "Backend"
1851+
" {:<18} {:>7} {:>8} {:>8} {:>8} {:>8} {:>8} Backend",
1852+
"Scenario", "Type", "p50", "p95", "p99", "p99.9", "max"
18581853
);
18591854
println!("{}", "-".repeat(w));
18601855

@@ -1916,8 +1911,7 @@ fn print_overhead_analysis(results: &[ScenarioResult]) {
19161911
let Some(floor_ns) = hw_floor else { return };
19171912

19181913
println!(
1919-
"{} Framework Overhead (vs hardware floor: {}ns) {}",
1920-
"───",
1914+
"─── Framework Overhead (vs hardware floor: {}ns) {}",
19211915
floor_ns,
19221916
"─".repeat(BOX_W - 55)
19231917
);
@@ -1955,11 +1949,7 @@ fn print_overhead_analysis(results: &[ScenarioResult]) {
19551949
// ============================================================================
19561950

19571951
fn print_methodology(cal: &RdtscCalibration) {
1958-
println!(
1959-
"{} Methodology {}",
1960-
"───",
1961-
"─".repeat(BOX_W - 18)
1962-
);
1952+
println!("─── Methodology {}", "─".repeat(BOX_W - 18));
19631953
println!();
19641954
println!(" Measurement types:");
19651955
println!(" send = producer-side send() latency (RDTSC, overhead subtracted)");
@@ -1990,7 +1980,9 @@ fn print_methodology(cal: &RdtscCalibration) {
19901980
times[times.len() / 2]
19911981
);
19921982
println!(" Intra-process: RDTSC overhead subtracted from each sample");
1993-
println!(" Cross-process: RDTSC overhead subtracted (rdtsc on producer + rdtscp on consumer)");
1983+
println!(
1984+
" Cross-process: RDTSC overhead subtracted (rdtsc on producer + rdtscp on consumer)"
1985+
);
19941986
println!();
19951987

19961988
println!(" Known limitations:");
@@ -2035,11 +2027,7 @@ fn write_json_output(path: &str, platform: &PlatformInfo, results: &[ScenarioRes
20352027
raw_latencies_ns: Vec::new(),
20362028
statistics: s.clone(),
20372029
throughput: ThroughputMetrics {
2038-
messages_per_sec: if s.mean > 0.0 {
2039-
1e9 / s.mean
2040-
} else {
2041-
0.0
2042-
},
2030+
messages_per_sec: if s.mean > 0.0 { 1e9 / s.mean } else { 0.0 },
20432031
bytes_per_sec: if s.mean > 0.0 {
20442032
(std::mem::size_of::<CmdVel>() as f64) * 1e9 / s.mean
20452033
} else {
@@ -2106,12 +2094,7 @@ fn box_center(text: &str) -> String {
21062094
let pad = BOX_W.saturating_sub(text.len());
21072095
let left = pad / 2;
21082096
let right = pad - left;
2109-
format!(
2110-
"║ {}{}{} ║",
2111-
" ".repeat(left),
2112-
text,
2113-
" ".repeat(right)
2114-
)
2097+
format!("║ {}{}{} ║", " ".repeat(left), text, " ".repeat(right))
21152098
}
21162099
fn box_left(text: &str) -> String {
21172100
let content = if text.len() > BOX_W {

benchmarks/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,3 @@ where
173173
std::hint::black_box(());
174174
}
175175
}
176-

benchmarks/src/timing.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,5 +331,4 @@ mod tests {
331331
min_latency
332332
);
333333
}
334-
335334
}

0 commit comments

Comments
 (0)