Meetily Model Download Manager Architecture: Progress Tracking, Cancellation, and Corruption Detection
Meetily's model download manager uses a Rust-based ModelManager struct with Arc<RwLock<…>> state management to track download lifecycles, report granular progress via callbacks, support HTTP Range resumption for cancellation, and validate GGUF magic numbers to detect corruption.
The architecture resides in the Tauri backend of Zackriya-Solutions/meetily, specifically within the summarization engine module. It handles built-in AI models for LLM features through a robust state machine that transitions between NotDownloaded, Downloading, Available, Corrupted, and Error states. All operations are thread-safe, allowing concurrent UI interactions while maintaining data integrity across async download tasks.
Core Architecture and Data Structures
ModelManager Struct and Thread Safety
The central orchestrator is the ModelManager struct defined in [frontend/src-tauri/src/summary/summary_engine/model_manager.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/summary_engine/model_manager.rs#L10-L22). It encapsulates:
- The models directory path
- A map of model metadata (
HashMap<String, ModelInfo>) - A set of active downloads to prevent concurrent operations
- A cancellation flag for graceful shutdowns
All mutable state is protected behind Arc<RwLock<…>> wrappers, enabling safe sharing across async tasks without data races.
ModelStatus Enum and State Machine
The lifecycle of every model is encoded in the ModelStatus enum (lines 60‑76):
pub enum ModelStatus {
NotDownloaded,
Downloading { progress: f32 },
Available,
Corrupted { size: u64, expected_minimum: u64 },
Error(String),
}
This five-state design allows the UI to distinguish between a model that has never been downloaded, one currently in progress, a verified available asset, or a corrupted file requiring re-download.
DownloadProgress and Real-time Reporting
Fine-grained progress reporting uses the DownloadProgress struct (lines 23‑38), which tracks:
- Bytes downloaded and total bytes
- Megabytes representation for UI display
- Transfer speed in MB/s
- Percentage completion
The manager emits these updates through a callback mechanism: Box<dyn Fn(DownloadProgress)> passed into the download method, allowing the Tauri frontend to receive real-time updates without polling.
Download Flow with Progress and Resumption
HTTP Range Requests and Partial File Handling
The download_model_detailed method implements resumable downloads via HTTP Range headers. When initiating a download, the manager first checks for existing partial files:
let existing_size = if file_path.exists() {
std::fs::metadata(&file_path)?.len()
} else { 0 };
// Request resume if partial file exists
if existing_size > 0 {
// Add header: Range: bytes=<existing>-
}
If the server supports partial content (HTTP 206), the manager opens the file in append mode using OpenOptions::append(true) and continues from the existing byte offset.
Chunked Streaming and Progress Calculation
The download loop streams data using an 8 MiB buffered writer (BufWriter). After each chunk:
- Write to disk and flush the buffer
- Update the running byte counter
- Calculate percentage and speed (MB/s)
- Determine if a progress event should fire (on every percent change or every 500ms)
During each iteration, the manager checks the cancellation flag via Arc<RwLock<bool>> comparison, allowing immediate but graceful termination.
Cancellation Mechanism
Cancellation is handled through a non-blocking flag pattern. The cancel_download method (lines 95‑115) writes the target model name into cancel_download_flag, which the download loop inspects after each chunk write:
if cancel_flag.as_ref() == Some(&model_name.to_string()) {
writer.flush()?;
*status = ModelStatus::NotDownloaded;
return Err("CANCELLED".into());
}
When cancelled, the method flushes the BufWriter to preserve partial data and returns an error. The partial file remains on disk, enabling seamless resumption when the user restarts the download.
Corruption Detection and Validation
Startup Scanning and Size Validation
Upon initialization (init() → scan_models()), the manager validates existing files against the metadata defined in models.rs. The corruption detection logic (lines 24‑56) implements a ±10% size tolerance:
- If the file size matches expected dimensions →
ModelStatus::Available - If the size deviates beyond tolerance →
ModelStatus::Corruptedwith recorded actual and expected sizes - If the file is missing →
ModelStatus::NotDownloaded
This heuristic catches incomplete downloads or filesystem corruption before the model is loaded into memory.
Post-Download GGUF Verification
After the byte stream completes, validate_gguf_file (lines 72‑92) performs a magic number check. The function reads the first four bytes and validates against the GGUF signature (b"GGUF"):
let mut buffer = [0u8; 4];
file.read_exact(&mut buffer)?;
if &buffer != b"GGUF" {
// Mark as Error and delete file
}
If validation fails, the manager immediately deletes the corrupted file and transitions the status to Error(String), preventing runtime crashes from invalid model formats.
Integration with the Tauri Frontend
The Rust backend exposes functionality through Tauri commands in [frontend/src-tauri/src/commands.rs](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/commands.rs):
whisper_download_model(line 452): WrapsModelManager::download_modelwith progress callback serialization to the JavaScript frontendwhisper_cancel_download(line 496): InvokesModelManager::cancel_downloadto set the cancellation flag
The frontend receives structured progress updates containing bytes, MB, speed, and percentage, enabling rich UI progress bars with transfer rate indicators.
Code Examples
Starting a Download with Progress Callback
use meetily::summary::summary_engine::model_manager::ModelManager;
let manager = ModelManager::new()?;
manager.init().await?;
manager
.download_model_detailed(
"gemma_1b",
Some(Box::new(|progress| {
println!(
"Progress: {:.1}% ({:.2} MB / {:.2} MB @ {:.2} MB/s)",
progress.percent,
progress.downloaded_mb,
progress.total_mb,
progress.speed_mbps
);
})),
)
.await?;
Cancelling an Active Download
let manager = ModelManager::new()?;
manager.cancel_download("gemma_1b").await?;
The cancellation flag is set immediately; the download loop detects it within the next chunk iteration and preserves the partial file for resumption.
Checking Model Availability
let manager = ModelManager::new()?;
manager.init().await?;
if manager.is_model_ready("gemma_1b", true).await {
println!("Model validated and ready");
} else {
println!("Model missing, corrupted, or downloading");
}
Passing true forces a fresh filesystem scan, ensuring the status reflects recent disk changes.
Summary
- Thread-safe architecture:
ModelManagerusesArc<RwLock<…>>to share mutable state across async tasks safely - Resumable downloads: HTTP Range headers and append-mode file writing enable cancellation without data loss
- Real-time progress:
DownloadProgressstruct reports bytes, MB, speed, and percentage via callbacks to the frontend - Dual validation: File size checks on startup (±10% tolerance) and GGUF magic number verification post-download prevent corrupted models from entering the pipeline
- Graceful cancellation: Atomic flag checks within the download loop allow immediate termination while preserving partial files
Frequently Asked Questions
How does Meetily handle network interruptions during model downloads?
Meetily's download manager supports automatic resumption through HTTP Range requests. When a download starts, it checks for existing partial files and sends a Range: bytes=<existing>- header. If the server supports partial content (HTTP 206), the download continues from the interruption point. If the network fails or the user cancels, the partial file remains on disk, allowing seamless continuation without re-downloading completed bytes.
What happens if a downloaded model file is corrupted?
The manager implements two-stage validation. First, during startup scanning (scan_models), it checks if the file size falls within ±10% of the expected size, marking it as Corrupted if not. Second, after download completion, validate_gguf_file reads the first four bytes to verify the GGUF magic number. If either check fails, the file is deleted and the status becomes Error, requiring a fresh download.
Can users cancel a download and restart it later without losing progress?
Yes. When cancel_download is invoked, it sets a cancellation flag that the download loop checks after each chunk. Upon detection, the loop flushes the BufWriter and exits cleanly, leaving the partial file intact. The status reverts to NotDownloaded. When the user restarts the download, the manager detects the existing file size and issues an HTTP Range request to resume from that byte offset, preserving previous progress.
How does the frontend receive real-time download progress?
The backend uses a callback mechanism defined in download_model_detailed. It accepts a Box<dyn Fn(DownloadProgress)> closure that emits events containing bytes downloaded, total bytes, MB representation, transfer speed (MB/s), and percentage completion. These events are serialized through Tauri commands (whisper_download_model) and transmitted to the JavaScript frontend, enabling live progress bars without polling.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →