Struct Feed

Source
pub struct Feed {
    config: FeedConfig,
    pub execute_command_received: bool,
    pub profile_id_requested: i32,
    pub execution_blocked: bool,
    lock_error_get_feedschedule_entry: bool,
    pub last_ping_instant: Instant,
    pub database_ping_interval: Duration,
    pub lock_warn_inapplicable_command_signal_handler: bool,
    pub lock_error_channel_receive_termination: bool,
}
Expand description

Contains the configuration and the implementation for the feed control. Thread communication is as follows:

graph LR feed[Feed Control] --> food_injection[Food Injection] food_injection --> relay_manager[Relay Manager] relay_manager --> food_injection feed --> signal_handler[Signal Handler] signal_handler --> feed signal_handler --> food_injection messaging[Messaging] --> feed
Communication channel to relay manager is forwarded to implementation of FoodInjectionTrait. Signal handler is communicating with both directly: feed as well with implementation of FoodInjectionTrait.

Fields§

§config: FeedConfig

Configuration data for Feed control

§execute_command_received: bool

Communication from trait implementation: request to execute a certain feed profile has been received

§profile_id_requested: i32

Communication from trait implementation: id of feed profile to be executed requested externally

§execution_blocked: bool

Inhibition flag for further execution of feed profiles. It is set whenever errors occur during feeding and can be reset by external command.

§lock_error_get_feedschedule_entry: bool

Inhibition flag to avoid flooding the log file with repeated messages about failure to read feed schedule entry from the database

§last_ping_instant: Instant

recording when the last database ping happened

§database_ping_interval: Duration

database ping interval

§lock_warn_inapplicable_command_signal_handler: bool

Inhibition flag to avoid flooding the log file with repeated messages about having received inapplicable command

§lock_error_channel_receive_termination: bool

Inhibition flag to avoid flooding the log file with repeated messages about failure to receive termination signal via the channel

Implementations§

Source§

impl Feed

Source

pub fn new(config: FeedConfig, database_ping_interval: Duration) -> Feed

Creates a new Feed control instance.

This constructor initializes the feed control module with its configuration and a database interface for managing feed-related data. It also sets initial states for command reception, execution blocking, and internal logging inhibition flags.

§Arguments
  • config - Configuration data for the feed control, loaded from a TOML file.
  • database_ping_interval - A Duration instance, providing the interval to ping the database.
§Returns

A new Feed struct, ready for operation within the application loop.

Source

fn execute_feed( &mut self, profile_id: i32, food_injection: &mut impl FoodInjectionTrait, feed_channels: &mut FeedChannels, sql_interface_feed: &mut Box<dyn DatabaseInterfaceFeedTrait + Sync + Send>, ) -> (Result<(), ()>, bool)

Loads a specified feed profile from the database, executes it via food injection, and logs the event.

This private helper function orchestrates the process of executing a single feed profile. It first attempts to retrieve the full Feedpattern from the database. If successful, it then calls the food_injection trait method to actuate the feeder according to the pattern. Finally, it records the completed feed event in the database.

The function also monitors for a Quit command from the signal handler during the food injection process, indicating an early termination request.

§Arguments
  • profile_id - The unique identifier of the feed profile to be loaded and executed.
  • food_injection - A mutable reference to an object implementing the FoodInjectionTrait, responsible for the physical actuation of the feeder.
  • feed_channels - A mutable reference to the struct containing the channels.
  • sql_interface_feed - A boxed trait object representing the interface to the SQL database for feed-specific operations. This allows for dependency injection and mock implementations during testing.
§Returns

A tuple (Result<(), ()>, bool) where:

  • The first element is the overall result of the operation. It is Ok(()) only if the food injection and the database logging both complete without error.
  • The second element is a bool, which is true if a Quit command was received from the signal handler during the inject_food process, false otherwise. This value is independent of the success or failure of the operation itself.
§Errors

This function does not return a distinct error type. Instead, it returns Err(()) in the result tuple to signify failure. The function can fail if:

  • It cannot read the specified feed pattern from the database.
  • The food_injection.inject_food method reports an error.
  • It cannot retrieve the current timestamp from the database after injection.
  • It fails to insert the feed event log into the database.

In all failure cases, a detailed error message is logged to the console.

Source

fn select_feed_schedule_entry_for_execution( &self, feedschedule_entries: &[FeedScheduleEntry], ) -> Option<FeedScheduleEntry>

Selects a specific feed schedule entry for execution based on the configured strategy.

This function is used when multiple FeedScheduleEntry items are found to be in the past (i.e., overdue for execution). It applies the strategy_multiple_schedule_entries_in_past from the FeedConfig to determine which single entry, if any, should be executed.

The strategy is defined as follows:

  • Negative value: No entry will be selected for execution.
  • Positive value (N): The N-th entry from the feedschedule_entries vector (0-indexed) will be selected.
    • If N is greater than or equal to the number of available entries, the last entry in the vector is selected.
§Arguments
  • feedschedule_entries - A slice of FeedScheduleEntry structs, assumed to be ordered.
§Returns

An Option<FeedScheduleEntry>:

  • Some(FeedScheduleEntry): The selected feed schedule entry to be executed.
  • None: If no entry is selected based on the strategy (e.g., negative strategy value, or an empty feedschedule_entries vector).
Source

fn execute_profile_update_database( &mut self, profile_id: i32, food_injection: &mut impl FoodInjectionTrait, feed_channels: &mut FeedChannels, feed_schedule_entries: &mut Vec<FeedScheduleEntry>, sql_interface_feed: &mut Box<dyn DatabaseInterfaceFeedTrait + Sync + Send>, ) -> bool

Executes a specified feed profile and updates the feed schedule in the database.

This function is a core part of the feed control logic. It first calls execute_feed to perform the actual food injection and log the event. Based on the outcome of execute_feed, it updates the internal execution_blocked flag if an error occurs. Finally, it triggers the update or deletion of the corresponding entries in the feed schedule database.

§Arguments
  • profile_id - The numeric identifier of the feed profile to be executed.
  • food_injection - A mutable reference to an object implementing FoodInjectionTrait, responsible for physical feeder actuation.
  • feed_channels - A mutable reference to the struct FoodInjectionTrait containing the channels.
  • rx_feed_from_relay_manager - The receiver channel for receiving acknowledgments from the relay manager.
  • rx_feed_from_signal_handler - The receiver channel for listening to signals (e.g., Quit) from the signal handler.
  • feed_schedule_entries - A mutable reference to the vector of FeedScheduleEntry that includes the entry(ies) just executed, which will be updated/deleted in the database.
  • sql_interface_feed - A boxed trait object representing the interface to the SQL database for feed-specific operations. This allows for dependency injection and mock implementations during testing.
§Returns

A bool which is true if a Quit command was received from the signal handler during the feed execution, indicating that the application should shut down; otherwise false.

Source

pub fn execute( &mut self, mutex_device_scheduler_feed: Arc<Mutex<i32>>, feed_channels: &mut FeedChannels, food_injection: &mut impl FoodInjectionTrait, sql_interface_feed: Box<dyn DatabaseInterfaceFeedTrait + Sync + Send>, )

Executes the main control loop for the feed module.

This function runs continuously, managing the automatic execution of feed profiles based on a schedule, processing external commands, and ensuring graceful shutdown. It periodically checks the database for overdue feed schedule entries and executes selected profiles, while also handling Start, Stop, and Execute commands received from external channels.

The loop breaks when a Quit command is received from the signal handler. After breaking, it sends a confirmation back to the signal handler and then waits for a Terminate command to ensure a complete shutdown.

§Arguments
  • mutex_device_scheduler_feed - An Arc<Mutex<i32>> used for coordinating access to device scheduling, preventing parallel actuation across different control modules. It holds a counter of the completed actuation.
  • feed_channels - A mutable reference to FeedChannels struct containing all necessary mpsc sender and receiver channels for inter-thread communication (e.g., with the signal handler, relay manager, and messaging).
  • food_injection - A mutable reference to an object implementing the FoodInjectionTrait, responsible for the physical dispensing of food.
  • sql_interface_feed - A boxed trait object representing the interface to the SQL database for feed-specific operations. This allows for dependency injection and mock implementations during testing.

Trait Implementations§

Source§

impl DatabasePingTrait for Feed

Source§

fn get_ping_interval(&self) -> Duration

Gets the interval at which the resource should be pinged.
Source§

fn get_last_ping_instant(&self) -> Instant

Gets the timestamp of the last successful ping.
Source§

fn update_last_ping_instant(&mut self)

Updates the timestamp of the last successful ping.
Source§

fn check_timing_and_ping_database( &mut self, database_interface: &mut (impl Pingable + ?Sized), )

Pings the database.
Source§

impl ProcessExternalRequestTrait for Feed

Source§

fn process_external_request( &mut self, rx_from_signal_handler: &mut AquaReceiver<InternalCommand>, rx_from_messaging_opt: Option<&mut AquaReceiver<InternalCommand>>, ) -> (bool, bool, bool)

Checks for and processes new commands relevant to the Feed control module from external channels.

This is the specialized implementation of ProcessExternalRequestTrait for the Feed module. It handles standard “Terminate” or “Quit” commands from the signal handler. From the messaging channel, it specifically processes “Start,” “Stop,” “ResetAllErrors,” and “Execute” commands, updating internal state variables based on these commands. Inapplicable commands are ignored with warnings.

§Arguments
  • rx_from_signal_handler - A reference to the receiver end of the channel for commands originating from the signal handler.
  • rx_from_messaging_opt - An Option containing a reference to the receiver end of the channel for commands from the messaging system. This channel is optional.
§Returns

A tuple (bool, bool, bool) indicating the status of specific commands received:

  • The first bool is true if a Quit or Terminate command was received from the signal handler; otherwise false.
  • The second bool is true if a Start command was received from messaging; otherwise false.
  • The third bool is true if a Stop command was received from messaging; otherwise false.
Source§

impl WaitForTerminationTrait for Feed

Source§

fn get_warn_lock_mut(&mut self) -> &mut bool

Method connects the default trait implementation with the specific implementation accessing the warn-lock.

Source§

fn get_error_lock_mut(&mut self) -> &mut bool

Method connects the default trait implementation with the specific implementation for accessing the error-lock.

Source§

fn wait_for_termination( &mut self, rx_waiting_thread_from_signal_handler: &mut AquaReceiver<InternalCommand>, sleep_duration: Duration, origin: &str, )

Implements the graceful shutdown wait loop for several threads (default implementation). Read more

Auto Trait Implementations§

§

impl Freeze for Feed

§

impl RefUnwindSafe for Feed

§

impl Send for Feed

§

impl Sync for Feed

§

impl Unpin for Feed

§

impl UnwindSafe for Feed

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> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T