Skip to content

Commit 5ae2a94

Browse files
committed
Enabling Worker features in Executor
Signed-off-by: Michael X. Grey <[email protected]>
1 parent 8fed9dd commit 5ae2a94

File tree

11 files changed

+456
-170
lines changed

11 files changed

+456
-170
lines changed

rclrs/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ unsafe impl Send for rcl_context_t {}
6363
/// (as well as the terminal). TODO: This behaviour should be configurable using an
6464
/// "auto logging initialise" flag as per rclcpp and rclpy.
6565
///
66+
#[derive(Clone)]
6667
pub struct Context {
6768
pub(crate) handle: Arc<ContextHandle>,
6869
}
@@ -191,7 +192,7 @@ impl Context {
191192
///
192193
/// [1]: BasicExecutorRuntime
193194
pub fn create_basic_executor(&self) -> Executor {
194-
let runtime = BasicExecutorRuntime::new(self);
195+
let runtime = BasicExecutorRuntime::new();
195196
self.create_executor(runtime)
196197
}
197198

rclrs/src/error.rs

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,31 @@ pub enum RclrsError {
4545
}
4646
}
4747

48+
impl RclrsError {
49+
/// Returns true if the error was due to a timeout, otherwise returns false.
50+
pub fn is_timeout(&self) -> bool {
51+
matches!(
52+
self,
53+
RclrsError::RclError {
54+
code: RclReturnCode::Timeout,
55+
..
56+
}
57+
)
58+
}
59+
60+
/// Returns true if the error was because a subscription, service, or client
61+
/// take failed, otherwise returns false.
62+
pub fn is_take_failed(&self) -> bool {
63+
matches!(
64+
self,
65+
RclrsError::RclError {
66+
code: RclReturnCode::SubscriptionTakeFailed | RclReturnCode::ServiceTakeFailed | RclReturnCode::ClientTakeFailed,
67+
..
68+
}
69+
)
70+
}
71+
}
72+
4873
impl Display for RclrsError {
4974
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5075
match self {
@@ -382,45 +407,79 @@ impl ToResult for rcl_ret_t {
382407

383408
/// A helper trait to disregard timeouts as not an error.
384409
pub trait RclrsErrorFilter {
410+
/// Get the first error available, or Ok(()) if there are no errors.
411+
fn first_error(self) -> Result<(), RclrsError>;
412+
385413
/// If the result was a timeout error, change it to `Ok(())`.
386-
fn timeout_ok(self) -> Result<(), RclrsError>;
414+
fn timeout_ok(self) -> Self;
387415

388416
/// If a subscription, service, or client take failed, change the result
389417
/// to be `Ok(())`.
390-
fn take_failed_ok(self) -> Result<(), RclrsError>;
418+
fn take_failed_ok(self) -> Self;
419+
420+
/// Some error types just indicate an early termination but do not indicate
421+
/// that anything in the system has misbehaved. This filters out anything
422+
/// that is part of the normal operation of rcl.
423+
fn ignore_non_errors(self) -> Self
424+
where
425+
Self: Sized,
426+
{
427+
self
428+
.timeout_ok()
429+
.take_failed_ok()
430+
}
391431
}
392432

393433
impl RclrsErrorFilter for Result<(), RclrsError> {
434+
fn first_error(self) -> Result<(), RclrsError> {
435+
self
436+
}
437+
394438
fn timeout_ok(self) -> Result<(), RclrsError> {
395439
match self {
396440
Ok(()) => Ok(()),
397441
Err(err) => {
398-
if matches!(
399-
err,
400-
RclrsError::RclError {
401-
code: RclReturnCode::Timeout,
402-
..
403-
}
404-
) {
405-
return Ok(());
442+
if err.is_timeout() {
443+
Ok(())
444+
} else {
445+
Err(err)
406446
}
407-
408-
Err(err)
409447
}
410448
}
411449
}
412450

413451
fn take_failed_ok(self) -> Result<(), RclrsError> {
414452
match self {
415-
Err(RclrsError::RclError {
416-
code: RclReturnCode::SubscriptionTakeFailed | RclReturnCode::ServiceTakeFailed | RclReturnCode::ClientTakeFailed,
417-
..
418-
}) => {
419-
// Spurious wakeup - this may happen even when a waitset indicated that
420-
// work was ready, so we won't report it as an error
421-
Ok(())
453+
Err(err) => {
454+
if err.is_take_failed() {
455+
// Spurious wakeup - this may happen even when a waitset indicated that
456+
// work was ready, so we won't report it as an error
457+
Ok(())
458+
} else {
459+
Err(err)
460+
}
422461
}
423462
other => other,
424463
}
425464
}
426465
}
466+
467+
impl RclrsErrorFilter for Vec<RclrsError> {
468+
fn first_error(mut self) -> Result<(), RclrsError> {
469+
if self.is_empty() {
470+
return Ok(());
471+
}
472+
473+
Err(self.remove(0))
474+
}
475+
476+
fn timeout_ok(mut self) -> Self {
477+
self.retain(|err| !err.is_timeout());
478+
self
479+
}
480+
481+
fn take_failed_ok(mut self) -> Self {
482+
self.retain(|err| !err.is_take_failed());
483+
self
484+
}
485+
}

0 commit comments

Comments
 (0)