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 send_message(&mut self, msg: CommandMessage) -> u32
pub fn send_message(&mut self, msg: CommandMessage) -> u32
Send an arbitrary CommandMessage.
Useful for sending specific MessageType requests like Read or Write.
Returns the transaction_id which can be used to match the response.
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 subscribe(&mut self, topic: &str)
pub fn subscribe(&mut self, topic: &str)
Register interest in a broadcast topic. After this call, any
incoming CommandMessage with this exact topic is buffered for
retrieval via take_broadcasts.
Idempotent — calling subscribe for an already-subscribed topic
does not reset the buffer.
Topics are matched as exact strings. The AMS asset-update wire
uses one topic per location (ams.asset_updated.tsdr_fx), so a
control program that cares about three load cells calls
subscribe three times.
Sourcepub fn take_broadcasts(&mut self, topic: &str) -> Vec<CommandMessage>
pub fn take_broadcasts(&mut self, topic: &str) -> Vec<CommandMessage>
Drain every buffered broadcast on the given topic, in arrival order. Returns an empty Vec if the topic isn’t subscribed or nothing has arrived since the last drain.
Recommended cadence: call once per tick from the subsystem
that owns the topic, right after the framework’s poll().
Sourcepub fn buffered_broadcast_count(&self) -> usize
pub fn buffered_broadcast_count(&self) -> usize
Number of buffered broadcasts across every subscribed topic.
Useful for diagnostics; the normal consumption path is
take_broadcasts per topic.
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.