Skip to content

Commit fc64af2

Browse files
authored
Error propagation and handling (#24)
* error handling for step and shutdown * fixed step error handling * update mini-adas for testing step and shutdown error propagation * update design docs for step and shutdown error propagation * update testing doc * remove failure handling sequence diagrams * remove testing doc from mini-adas
1 parent 628df66 commit fc64af2

File tree

10 files changed

+162
-49
lines changed

10 files changed

+162
-49
lines changed

examples/rust/cycle-benchmark/src/activities.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
********************************************************************************/
1313

1414
use feo::activity::Activity;
15+
use feo::error::ActivityError;
1516
use feo::ids::ActivityId;
1617
use feo_tracing::{instrument, tracing};
1718

@@ -42,10 +43,13 @@ impl Activity for DummyActivity {
4243
fn startup(&mut self) {}
4344

4445
#[instrument(name = "Activity step")]
45-
fn step(&mut self) {
46+
fn step(&mut self) -> Result<(), ActivityError> {
4647
tracing::event!(tracing::Level::TRACE, id = self._id_str);
48+
Ok(())
4749
}
4850

4951
#[instrument(name = "Activity shutdown")]
50-
fn shutdown(&mut self) {}
52+
fn shutdown(&mut self) -> Result<(), ActivityError> {
53+
Ok(())
54+
}
5155
}

examples/rust/cycle-benchmark/src/composites.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use crate::activities::DummyActivity;
1515
use crate::config::ActivityDependencies;
1616
use feo::activity::{Activity, ActivityBuilder, ActivityIdAndBuilder};
17+
use feo::error::ActivityError;
1718
use feo::ids::{ActivityId, WorkerId};
1819
use feo_tracing::{instrument, tracing};
1920
use std::collections::{HashMap, HashSet};
@@ -55,18 +56,20 @@ impl Activity for CompositeActivity {
5556
}
5657

5758
#[instrument(name = "Composite step")]
58-
fn step(&mut self) {
59+
fn step(&mut self) -> Result<(), ActivityError> {
5960
tracing::event!(tracing::Level::TRACE, id = self._activity_id_str);
6061
for activity in &mut self.activities {
61-
activity.step();
62+
activity.step()?;
6263
}
64+
Ok(())
6365
}
6466

6567
#[instrument(name = "Composite shutdown")]
66-
fn shutdown(&mut self) {
68+
fn shutdown(&mut self) -> Result<(), ActivityError> {
6769
for activity in &mut self.activities {
68-
activity.shutdown();
70+
activity.shutdown()?;
6971
}
72+
Ok(())
7073
}
7174
}
7275

examples/rust/mini-adas/src/activities/components.rs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use core::mem::MaybeUninit;
1818
use core::ops::{Deref, DerefMut, Range};
1919
use core::time::Duration;
2020
use feo::activity::Activity;
21+
use feo::error::ActivityError;
2122
use feo::ids::ActivityId;
2223
use feo_com::interface::{ActivityInput, ActivityOutput};
2324
#[cfg(feature = "com_iox2")]
@@ -28,7 +29,6 @@ use feo_log::debug;
2829
use feo_tracing::instrument;
2930
use std::hash::RandomState;
3031
use std::thread;
31-
3232
const SLEEP_RANGE: Range<i64> = 10..45;
3333

3434
/// Camera activity
@@ -85,7 +85,7 @@ impl Activity for Camera {
8585
fn startup(&mut self) {}
8686

8787
#[instrument(name = "Camera")]
88-
fn step(&mut self) {
88+
fn step(&mut self) -> Result<(), ActivityError> {
8989
debug!("Stepping Camera");
9090
sleep_random();
9191

@@ -95,11 +95,13 @@ impl Activity for Camera {
9595
let camera = camera.write_payload(image);
9696
camera.send().unwrap();
9797
}
98+
Ok(())
9899
}
99100

100101
#[instrument(name = "Camera shutdown")]
101-
fn shutdown(&mut self) {
102+
fn shutdown(&mut self) -> Result<(), ActivityError> {
102103
debug!("Shutting down Camera activity {}", self.activity_id);
104+
Ok(())
103105
}
104106
}
105107

@@ -150,7 +152,7 @@ impl Activity for Radar {
150152
fn startup(&mut self) {}
151153

152154
#[instrument(name = "Radar")]
153-
fn step(&mut self) {
155+
fn step(&mut self) -> Result<(), ActivityError> {
154156
debug!("Stepping Radar");
155157
sleep_random();
156158

@@ -160,11 +162,13 @@ impl Activity for Radar {
160162
let radar = radar.write_payload(scan);
161163
radar.send().unwrap();
162164
}
165+
Ok(())
163166
}
164167

165168
#[instrument(name = "Radar shutdown")]
166-
fn shutdown(&mut self) {
169+
fn shutdown(&mut self) -> Result<(), ActivityError> {
167170
debug!("Shutting down Radar activity {}", self.activity_id);
171+
Ok(())
168172
}
169173
}
170174

@@ -235,7 +239,7 @@ impl Activity for NeuralNet {
235239
fn startup(&mut self) {}
236240

237241
#[instrument(name = "NeuralNet")]
238-
fn step(&mut self) {
242+
fn step(&mut self) -> Result<(), ActivityError> {
239243
debug!("Stepping NeuralNet");
240244
sleep_random();
241245

@@ -252,11 +256,13 @@ impl Activity for NeuralNet {
252256
debug!("Sending Scene {:?}", scene.deref());
253257
scene.send().unwrap();
254258
}
259+
Ok(())
255260
}
256261

257262
#[instrument(name = "NeuralNet shutdown")]
258-
fn shutdown(&mut self) {
263+
fn shutdown(&mut self) -> Result<(), ActivityError> {
259264
debug!("Shutting down NeuralNet activity {}", self.activity_id);
265+
Ok(())
260266
}
261267
}
262268

@@ -299,7 +305,7 @@ impl Activity for EmergencyBraking {
299305
fn startup(&mut self) {}
300306

301307
#[instrument(name = "EmergencyBraking")]
302-
fn step(&mut self) {
308+
fn step(&mut self) -> Result<(), ActivityError> {
303309
debug!("Stepping EmergencyBraking");
304310
sleep_random();
305311

@@ -331,14 +337,16 @@ impl Activity for EmergencyBraking {
331337
brake_instruction.send().unwrap();
332338
}
333339
}
340+
Ok(())
334341
}
335342

336343
#[instrument(name = "EmergencyBraking shutdown")]
337-
fn shutdown(&mut self) {
344+
fn shutdown(&mut self) -> Result<(), ActivityError> {
338345
debug!(
339346
"Shutting down EmergencyBraking activity {}",
340347
self.activity_id
341348
);
349+
Ok(())
342350
}
343351
}
344352

@@ -374,7 +382,7 @@ impl Activity for BrakeController {
374382
fn startup(&mut self) {}
375383

376384
#[instrument(name = "BrakeController")]
377-
fn step(&mut self) {
385+
fn step(&mut self) -> Result<(), ActivityError> {
378386
debug!("Stepping BrakeController");
379387
sleep_random();
380388

@@ -386,14 +394,16 @@ impl Activity for BrakeController {
386394
)
387395
}
388396
}
397+
Ok(())
389398
}
390399

391400
#[instrument(name = "BrakeController shutdown")]
392-
fn shutdown(&mut self) {
401+
fn shutdown(&mut self) -> Result<(), ActivityError> {
393402
debug!(
394403
"Shutting down BrakeController activity {}",
395404
self.activity_id
396405
);
406+
Ok(())
397407
}
398408
}
399409

@@ -428,21 +438,23 @@ impl Activity for EnvironmentRenderer {
428438
fn startup(&mut self) {}
429439

430440
#[instrument(name = "EnvironmentRenderer")]
431-
fn step(&mut self) {
441+
fn step(&mut self) -> Result<(), ActivityError> {
432442
debug!("Stepping EnvironmentRenderer");
433443
sleep_random();
434444

435445
if let Ok(_scene) = self.input_scene.read() {
436446
debug!("Rendering scene");
437447
}
448+
Ok(())
438449
}
439450

440451
#[instrument(name = "EnvironmentRenderer shutdown")]
441-
fn shutdown(&mut self) {
452+
fn shutdown(&mut self) -> Result<(), ActivityError> {
442453
debug!(
443454
"Shutting down EnvironmentRenderer activity {}",
444455
self.activity_id
445456
);
457+
Ok(())
446458
}
447459
}
448460

@@ -478,7 +490,7 @@ impl Activity for SteeringController {
478490
fn startup(&mut self) {}
479491

480492
#[instrument(name = "SteeringController")]
481-
fn step(&mut self) {
493+
fn step(&mut self) -> Result<(), ActivityError> {
482494
debug!("Stepping SteeringController");
483495
sleep_random();
484496

@@ -488,14 +500,16 @@ impl Activity for SteeringController {
488500
steering.angle
489501
)
490502
}
503+
Ok(())
491504
}
492505

493506
#[instrument(name = "SteeringController shutdown")]
494-
fn shutdown(&mut self) {
507+
fn shutdown(&mut self) -> Result<(), ActivityError> {
495508
debug!(
496509
"Shutting down SteeringController activity {}",
497510
self.activity_id
498511
);
512+
Ok(())
499513
}
500514
}
501515

feo/src/activity.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
********************************************************************************/
1313

1414
//! Activity and related structs and traits
15+
use crate::error::ActivityError;
1516
use crate::ids::ActivityId;
1617
use alloc::boxed::Box;
1718

@@ -24,10 +25,10 @@ pub trait Activity {
2425
fn startup(&mut self);
2526

2627
/// Called upon each step
27-
fn step(&mut self);
28+
fn step(&mut self) -> Result<(), ActivityError>;
2829

2930
/// Called upon shutdown
30-
fn shutdown(&mut self);
31+
fn shutdown(&mut self) -> Result<(), ActivityError>;
3132
}
3233

3334
/// Activity Builder trait.

feo/src/cpp.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
//! Provides a convenience macro creating ffi definitions and Rust glue code for C++ components
1515
16-
/// Create ffi definitions and Rust glue code for a C++ component
16+
/// Create ffi definitions and Rust glue code for a C++ component
1717
///
1818
/// Call: `cpp_activity!(name, library)`
1919
///
@@ -34,6 +34,7 @@ macro_rules! cpp_activity {
3434
( $name:ident, $library:literal ) => {
3535
pub mod $name {
3636
use feo::activity::Activity;
37+
use feo::error::ActivityError;
3738
use feo::ids::ActivityId;
3839
use feo_cpp_macros::{make_fn, make_fn_call};
3940
use feo_tracing::{instrument, tracing};
@@ -91,15 +92,17 @@ macro_rules! cpp_activity {
9192
}
9293

9394
#[instrument(name = "step")]
94-
fn step(&mut self) {
95+
fn step(&mut self) -> Result<(), ActivityError> {
9596
// Safety: Call of external C functions belonging to C++ activitiy, to be reviewed
9697
unsafe { make_fn_call!($name, _step, (self.cpp_activity)) };
98+
Ok(())
9799
}
98100

99101
#[instrument(name = "shutdown")]
100-
fn shutdown(&mut self) {
102+
fn shutdown(&mut self) -> Result<(), ActivityError> {
101103
// Safety: Call of external C functions belonging to C++ activitiy, to be reviewed
102104
unsafe { make_fn_call!($name, _shutdown, (self.cpp_activity)) };
105+
Ok(())
103106
}
104107
}
105108
}

feo/src/error.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@
1616
use crate::ids::{ActivityId, ChannelId, WorkerId};
1717
use crate::signalling::common::signals::Signal;
1818
use core::time::Duration;
19+
#[cfg(feature = "recording")]
20+
use postcard::experimental::max_size::MaxSize;
21+
#[cfg(feature = "recording")]
22+
use serde::Deserialize;
23+
#[cfg(feature = "recording")]
24+
use serde::Serialize;
1925

2026
/// FEO Error type
2127
#[non_exhaustive]
2228
#[derive(Debug)]
2329
pub enum Error {
30+
ActivityFailed(ActivityId, ActivityError),
2431
ActivityNotFound(ActivityId),
2532
Channel(&'static str),
2633
ChannelClosed,
@@ -32,11 +39,24 @@ pub enum Error {
3239
WorkerNotFound(WorkerId),
3340
}
3441

42+
/// Defines the types of failures an Activity can report.
43+
#[cfg_attr(feature = "recording", derive(Serialize, Deserialize, MaxSize))]
44+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45+
pub enum ActivityError {
46+
/// A failure during a regular `step()` execution.
47+
Step,
48+
/// A failure during the `shutdown()` method.
49+
Shutdown,
50+
}
51+
3552
impl core::error::Error for Error {}
3653

3754
impl core::fmt::Display for Error {
3855
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
3956
match self {
57+
Error::ActivityFailed(id, err) => {
58+
write!(f, "activity {id} reported a failure: {err:?}")
59+
}
4060
Error::ActivityNotFound(id) => write!(f, "failed to find activity with ID {id}"),
4161
Error::Channel(description) => write!(f, "channel error: {description}"),
4262
Error::ChannelClosed => write!(f, "channel closed by peer"),

0 commit comments

Comments
 (0)