pub struct CommandClient { /* private fields */ }Expand description
A non-blocking client for sending IPC commands to external modules.
CommandClient is constructed by ControlRunner during
startup and passed to the control program each cycle via
TickContext::client.
All methods are non-blocking and safe to call from process_tick.
Multiple subsystems (state machines, modules) can share a single CommandClient.
Each subsystem calls send() to issue requests and
take_response() to claim its own responses by
transaction_id. The framework calls poll() once per tick
before process_tick, so incoming messages are already buffered.
Implementations§
Source§impl CommandClient
impl CommandClient
Sourcepub fn new(
write_tx: UnboundedSender<String>,
response_rx: UnboundedReceiver<CommandMessage>,
) -> Self
pub fn new( write_tx: UnboundedSender<String>, response_rx: UnboundedReceiver<CommandMessage>, ) -> Self
Create a new CommandClient from channels created by ControlRunner.
Sourcepub fn send(&mut self, topic: &str, data: Value) -> u32
pub fn send(&mut self, topic: &str, data: Value) -> u32
Send a command request to an external module.
Creates a CommandMessage::request with the given topic and data,
serializes it, and pushes it into the WebSocket write channel.
Returns the transaction_id which can be used to match the response.
§Arguments
topic- Fully-qualified topic name (e.g.,"labelit.translate_check")data- JSON payload for the request
Sourcepub fn poll(&mut self)
pub fn poll(&mut self)
Drain all available responses from the WebSocket channel into the internal buffer.
Call this once per tick at the top of process_tick, before any
subsystem calls take_response(). This ensures
every subsystem sees responses that arrived since the last cycle.
Sourcepub fn take_response(&mut self, transaction_id: u32) -> Option<CommandMessage>
pub fn take_response(&mut self, transaction_id: u32) -> Option<CommandMessage>
Take a response for a specific transaction_id from the buffer.
Returns Some(response) if a response with that ID has been received,
or None if it hasn’t arrived yet. The response is removed from the
buffer on retrieval.
This is the recommended way for subsystems to retrieve their responses,
since each subsystem only claims its own transaction_id and cannot
accidentally consume another subsystem’s response.
§Example
// In a subsystem's tick method:
if let Some(response) = client.take_response(self.my_tid) {
if response.success {
// handle success
} else {
// handle error
}
}Sourcepub fn is_pending(&self, transaction_id: u32) -> bool
pub fn is_pending(&self, transaction_id: u32) -> bool
Check if a request is still awaiting a response.
Returns true if the request has been sent but no response has arrived
yet. Returns false if the response is already buffered (even if not
yet claimed via take_response()) or if the
transaction ID is unknown.
Sourcepub fn pending_count(&self) -> usize
pub fn pending_count(&self) -> usize
Number of outstanding requests (sent but no response received yet).
Sourcepub fn response_count(&self) -> usize
pub fn response_count(&self) -> usize
Number of responses buffered and ready to be claimed.
Sourcepub fn drain_stale(&mut self, timeout: Duration) -> Vec<u32>
pub fn drain_stale(&mut self, timeout: Duration) -> Vec<u32>
Remove and return transaction IDs that have been pending longer than timeout.