downloader.rs
Overview
downloader.rs defines the StateDownloader struct and its asynchronous behavior for downloading state data from a specified URL. It listens for trigger signals on a channel (Receiver) and, upon receiving a signal, performs an HTTP GET request to fetch data from the provided URL. After a successful download, it sends an event notification (Event::StateDownloaded) through an event publishing channel (Sender). The file is primarily focused on handling the download workflow in response to external triggers and notifying other system components upon completion.
Detailed Breakdown
Struct: StateDownloader
The StateDownloader struct encapsulates the data and communication channels required to perform state downloads asynchronously.
Fields:
url: Url
The URL endpoint from which state data is downloaded. Uses theurl::Urltype for validated URL handling.rx: Receiver<()>
A receiving channel that listens for empty tuple signals()to trigger downloads. This channel is used to synchronize or request downloads externally.event_pub: Sender<Event>
A sending channel for publishing events related to the downloader's state, specifically signaling when a download has completed.
Implementation of StateDownloader
new(url: Url, rx: Receiver<()>, event_pub: Sender<Event>) -> Self
Creates a new instance of StateDownloader with the specified URL, receiver, and event sender.
Parameters:
url: The target URL for downloading state.rx: The channel receiver to listen for download triggers.event_pub: The channel sender to publish download completion events.
Returns:
A newStateDownloaderinstance.Usage Example:
let downloader = StateDownloader::new(url, rx_channel, event_sender);
async fn run(&self) -> anyhow::Result<()>
Runs the downloader's main event loop asynchronously. This method continuously listens on the rx channel for download triggers. Upon receiving a trigger, it performs an HTTP GET request to the configured URL. After a successful download, it emits an Event::StateDownloaded event via the event_pub channel.
Behavior:
Blocks waiting for a message on the
rxchannel.On receiving
Ok(()), performs an asynchronous HTTP GET request usingreqwest.If the download succeeds, sends an event notification.
If the
rxchannel is closed or an error occurs, the method returns an error wrapped inanyhow::Result.
Returns:
Ok(())if the loop exits successfully (which in the current infinite loop design would not happen unless the channel is closed), or an error of typeanyhow::Error.Errors:
Returns an error if:Receiving from the
rxchannel fails.The HTTP request fails.
Usage Example:
downloader.run().await?;Implementation Notes:
The method contains a
TODOcomment indicating plans for enhancing the download logic with retry and resume capabilities.Uses
reqwest::getfor HTTP requests, which requires additional asynchronous runtime support.Event publishing uses
expectto panic if event sending fails, implying that event subscribers must be alive during operation.
Implementation Details and Algorithms
The downloader listens on a channel for download triggers rather than running on a fixed schedule.
Upon trigger, it performs a simple HTTP GET request to download the entire resource at once.
The event system decouples the downloader from consumers interested in download completion, enabling asynchronous event-driven workflows.
Error handling uses
anyhowfor flexible error propagation.
Interaction with Other System Components
Events Module (
crate::events::Event):
The downloader sendsEvent::StateDownloadedto signal that a download has finished successfully. Other parts of the system listen for this event to react accordingly (e.g., processing or applying the downloaded state).Communication Channels:
The downloader relies on an external producer to send signals on therxchannel to initiate downloads, allowing external control of download timing.HTTP Client (
reqwest):
Uses thereqwestcrate for asynchronous HTTP GET requests.URL Handling (
urlcrate):
Ensures URLs are valid and parsed correctly.
Diagram: Structure of downloader.rs
classDiagram
class StateDownloader {
-url: Url
-rx: Receiver
-event_pub: Sender
+new()
+run() async
}
StateDownloader ..> Url : uses
StateDownloader ..> Receiver : listens on
StateDownloader ..> Sender : publishes events
StateDownloader ..> Event : sends Event::StateDownloaded