Skip to main content

ActionServerCore

Struct ActionServerCore 

Source
pub struct ActionServerCore<const GOAL_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#0}, const RESULT_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#1}, const FEEDBACK_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#2}, const MAX_GOALS: usize = 4> { /* private fields */ }
Expand description

Type-agnostic action server core handling the raw-bytes protocol.

Manages active goal tracking (GoalId + status), completed result storage in a fixed-size slab, and all CDR framing for the action protocol.

The typed ActionServer wraps this and adds A::Goal / A::Feedback / A::Result (de)serialization.

Implementations§

Source§

impl<const GOAL_BUF: usize, const RESULT_BUF: usize, const FEEDBACK_BUF: usize, const MAX_GOALS: usize> ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

Source

pub fn from_channels( send_goal_server: <CffiSession as Session>::ServiceHandle, cancel_goal_server: <CffiSession as Session>::ServiceHandle, get_result_server: <CffiSession as Session>::ServiceHandle, feedback_publisher: <CffiSession as Session>::PublisherHandle, status_publisher: <CffiSession as Session>::PublisherHandle, ) -> ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

Phase 122.3.c.6.b — construct an ActionServerCore from the 5 already-built transport channels. Caller (typically the C API’s nros_action_server_init_polling) owns wiring the channels via the session’s create_* methods.

Source

pub fn try_recv_goal_request( &mut self, ) -> Result<Option<RawGoalRequest>, NodeError>

Try to receive a goal request from the send_goal service.

Returns the parsed GoalId, sequence number, and data length. The full CDR data (including GoalId) remains in goal_buffer.

Source

pub fn goal_buffer(&self) -> &[u8]

Get a reference to the goal buffer (valid after try_recv_goal_request).

Source

pub fn accept_goal( &mut self, goal_id: GoalId, seq: i64, ) -> Result<(), NodeError>

Accept a goal: records it, sends the acceptance reply, publishes status.

§Ordering

The goal is recorded in active_goals before the reply goes out, and the recording is rolled back if the reply fails. Issue 0322: this used to reply first and then let _ = self.active_goals.push(...), so once MAX_GOALS (default 4) were active, a 5th send_goal was answered accepted=true and then dropped — no execution, no feedback, no result, no terminal status. An rclcpp/rclpy client that saw accepted=true waited on its result future forever.

A full table is now answered truthfully with accepted=false via Self::reject_goal, which is a contract the client already handles.

Source

pub fn reject_goal(&mut self, seq: i64) -> Result<(), NodeError>

Reject a goal: sends the rejection reply.

Source

pub fn publish_feedback_raw( &mut self, goal_id: &GoalId, feedback_cdr: &[u8], ) -> Result<(), NodeError>

Publish feedback with raw CDR bytes.

Writes GoalId framing + raw feedback bytes into the feedback buffer and publishes.

Source

pub fn set_goal_status(&mut self, goal_id: &GoalId, status: GoalStatus)

Set a goal’s status and publish the updated GoalStatusArray.

Source

pub fn expire_completed_results(&mut self) -> usize

Reclaim every completed result whose get_result reply has already been sent — nano-ros’s analogue of rcl_action_expire_goals(). Returns the number of entries reclaimed.

Calling this is optional: complete_goal_raw reclaims on demand, so a server that never calls it still runs forever. It exists for a server that would rather return the memory eagerly (e.g. before a long idle period) than at the next completion.

Source

pub fn completed_result_count(&self) -> usize

Number of completed results currently retained.

Source

pub fn result_slab_used(&self) -> usize

Bytes of the result slab currently held by retained results.

Source

pub fn has_completed_result(&self, goal_id: &GoalId) -> bool

true while goal_id’s completed result is still retained (i.e. a get_result for it would be answered from the slab rather than as Unknown).

Source

pub fn complete_goal_raw( &mut self, goal_id: &GoalId, status: GoalStatus, result_cdr: &[u8], ) -> Result<(), NodeError>

Complete a goal: remove from active, store raw result CDR in slab, publish status.

§Errors

NodeError::BufferTooSmall when result_cdr is larger than RESULT_BUF and therefore cannot be retained for a later get_result. Any client already waiting on ~/_action/get_result is still answered (straight from result_cdr), and the terminal status is still published — but a later get_result for this goal gets GoalStatus::Unknown. Raise the server’s RESULT_BUF.

Issue 0796: this returned (), so the pre-fix slab exhaustion — the server silently dropping every result once the bump allocator hit RESULT_BUF, and silently stranding every waiting requester with it — was invisible to the caller. A full slab is no longer a failure at all (it is reclaimed), and the one remaining failure is reported.

Source

pub fn register_goal_waker(&self, waker: &Waker)

Phase 122.3.c.6.e — register a Waker that fires when a new send_goal request arrives. Event-driven action servers register here in place of polling try_recv_goal_request on a timer.

Source

pub fn register_cancel_waker(&self, waker: &Waker)

Phase 122.3.c.6.e — register a Waker that fires when a cancel-goal request arrives.

Source

pub fn register_get_result_waker(&self, waker: &Waker)

Phase 122.3.c.6.e — register a Waker that fires when a get_result query arrives.

Source

pub fn try_recv_cancel_request( &mut self, ) -> Result<Option<PendingCancelRequest>, NodeError>

Phase 122.3.c.6.d — peek a pending cancel-goal request without generating a reply. Returns the goal_id named in the request, the matching service sequence number (use it with send_cancel_reply), and the goal’s current status (GoalStatus::Unknown if no such active goal). Returns Ok(None) when no cancel request is pending.

Used by L1 polling-mode action servers (nros-c / nros-cpp C FFI) that want to drive cancel-decision policy without passing a Rust closure across the C ABI. See the matching send_cancel_reply for the reply side. The high-level closure-based try_handle_cancel keeps working and now delegates to this pair.

Source

pub fn send_cancel_reply( &mut self, sequence_number: i64, return_code: CancelReturnCode, accepted: &[GoalId], ) -> Result<(), NodeError>

Phase 122.3.c.6.d — send the reply to a previously-peeked cancel-goal request. sequence_number must match the value returned by try_recv_cancel_request.

return_code is the overall RPC status (CancelReturnCode::Ok = at least one cancel honoured; other variants = whole-request failure). accepted lists the goals that transition to Canceling; this function flips their stored status before publishing the status array.

Issue 0796 — the parameter is a nros_core::CancelReturnCode, not the per-goal nros_core::CancelResponse a cancel callback returns. The two were one type and their discriminants overlap with opposite meanings (Reject/Ok are both 0), so this signature is what stops a per-goal answer being written into the RPC field.

Source

pub fn try_handle_cancel( &mut self, cancel_handler: impl FnOnce(&GoalId, GoalStatus) -> CancelResponse, ) -> Result<Option<(GoalId, CancelResponse)>, NodeError>

Try to handle a cancel_goal request (type-agnostic).

Source

pub fn try_handle_get_result_raw( &mut self, default_result_cdr: &[u8], ) -> Result<Option<GoalId>, NodeError>

Try to handle a get_result request using raw bytes.

For completed goals, sends the stored raw result CDR from the slab. For active/unknown goals, sends the provided default_result_cdr bytes.

default_result_cdr should contain serialized result data (without CDR header or status byte) — typically A::Result::default() serialized.

Source

pub fn active_goal_count(&self) -> usize

Get the number of active goals.

Source

pub fn active_goals(&self) -> &[RawActiveGoal]

Get a reference to all active goals.

Source

pub fn find_goal_status(&self, goal_id: &GoalId) -> GoalStatus

Find the status of a goal (active or unknown).

Source

pub fn publish_status_array(&self) -> Result<(), NodeError>

Publish the current GoalStatusArray on the status topic.

Auto Trait Implementations§

§

impl<const GOAL_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#0}, const RESULT_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#1}, const FEEDBACK_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#2}, const MAX_GOALS: usize = 4> !Send for ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

§

impl<const GOAL_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#0}, const RESULT_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#1}, const FEEDBACK_BUF: usize = nros_node::::executor::action_core::ActionServerCore::{constant#2}, const MAX_GOALS: usize = 4> !Sync for ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

§

impl<const GOAL_BUF: usize, const RESULT_BUF: usize, const FEEDBACK_BUF: usize, const MAX_GOALS: usize> Freeze for ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

§

impl<const GOAL_BUF: usize, const RESULT_BUF: usize, const FEEDBACK_BUF: usize, const MAX_GOALS: usize> RefUnwindSafe for ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

§

impl<const GOAL_BUF: usize, const RESULT_BUF: usize, const FEEDBACK_BUF: usize, const MAX_GOALS: usize> Unpin for ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

§

impl<const GOAL_BUF: usize, const RESULT_BUF: usize, const FEEDBACK_BUF: usize, const MAX_GOALS: usize> UnsafeUnpin for ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

§

impl<const GOAL_BUF: usize, const RESULT_BUF: usize, const FEEDBACK_BUF: usize, const MAX_GOALS: usize> UnwindSafe for ActionServerCore<GOAL_BUF, RESULT_BUF, FEEDBACK_BUF, MAX_GOALS>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.