Architecture of Meetily's Incremental Saver for Preventing Data Loss During Recordings
Meetily's incremental saver architecture employs a Tauri-based Rust core that writes audio chunks to numbered checkpoint files in real-time while atomically persisting transcript updates, ensuring meeting data survives unexpected crashes or power failures.
Meetily, developed by Zackriya-Solutions, is an open-source meeting recording application that captures audio locally using a robust Rust backend. The architecture of Meetily's incremental saver implements a multi-layered persistence strategy that combines checkpoint-based audio storage with atomic file operations to eliminate data loss risks during active recordings.
Core Components of the Incremental Architecture
Meetily's data protection system relies on three cooperating components that handle different aspects of the persistence lifecycle.
RecordingSaver: The Central Orchestrator
The RecordingSaver struct in frontend/src-tauri/src/audio/recording_saver.rs manages the entire saving flow. Its new() constructor initializes a clean state, while start_accumulation(auto_save) opens an unbounded channel for audio chunks and conditionally initializes the checkpoint system.
When auto_save is true, the orchestrator calls initialize_meeting_folder(..., true) to create the .checkpoints subdirectory alongside the standard meeting folder hierarchy. The saver also maintains an in-memory vector of transcript segments, immediately persisting each update to transcripts.json via add_transcript_segment() whenever new transcription data arrives.
IncrementalAudioSaver: Real-Time Checkpoint Management
The IncrementalAudioSaver struct in frontend/src-tauri/src/audio/incremental_saver.rs handles the audio-specific persistence logic. It is instantiated with IncrementalAudioSaver::new(meeting_folder.clone(), 48_000), where the second parameter specifies the audio sample rate (48 kHz).
During active recording, each incoming AudioChunk structure is immediately written to disk via saver_guard.add_chunk(chunk) inside the async accumulation loop. The saver creates numbered checkpoint files for each chunk, ensuring that already-written data survives even if the process terminates unexpectedly. When recording stops, finalize() merges all checkpoint files into the final audio.mp4 output.
Atomic File Writers for Metadata Integrity
To prevent corruption of JSON metadata, Meetily uses atomic file replacement operations. Both write_metadata and write_transcripts_json functions create temporary files first, then use std::fs::rename to atomically replace the existing files. This temp-then-rename pattern ensures that power failures never leave partially written metadata.json or transcripts.json files on disk.
The Incremental Saving Process
The architecture implements a four-stage pipeline that continuously protects data from capture to finalization.
Initialization and Folder Structure
The process begins with create_meeting_folder from frontend/src-tauri/src/audio/audio_processing.rs, which constructs the directory hierarchy at the base recordings path (typically ~/Library/Application Support/Meetily/recordings). The function creates <meeting-name>/ and optionally <meeting-name>/.checkpoints/ when checkpoint mode is enabled.
Real-Time Chunk Persistence
While recording, the system operates on an unbounded channel receiving AudioChunk structures defined in frontend/src-tauri/src/audio/recording_state.rs. Each chunk is serialized to a separate numbered file in the .checkpoints directory immediately upon arrival, providing chunk-by-chunk persistence that minimizes data loss windows to milliseconds rather than minutes.
Graceful Finalization
When the user stops recording, the stop_and_save method disables the accumulation loop and waits for in-flight chunks to complete. It then calls incremental_saver.finalize() to merge all checkpoint files into the final audio.mp4. After successful merge, the method updates metadata.json status to "completed" and emits a Tauri event "recording-saved" containing the final file paths.
Data Loss Prevention Mechanisms
Meetily implements four specific technical safeguards to ensure recording integrity:
-
Chunk-by-Chunk Persistence: Each
AudioChunkis written to a separate checkpoint file immediately upon receipt, ensuring that crash events only lose the most recent milliseconds of audio rather than the entire recording. -
Atomic Metadata Updates: All JSON file updates use a temporary file followed by
std::fs::rename, guaranteeing thatmetadata.jsonandtranscripts.jsonnever exist in a partially written state. -
Graceful Shutdown Sequences: The
stop_and_savemethod properly drains the audio channel before finalization, ensuring that buffers are flushed to disk before the merge operation begins. -
Optional Auto-Save Modes: When
auto_saveis set tofalse, the system disables audio checkpointing while maintaining transcript persistence, allowing users to prioritize transcription data over audio storage during resource-constrained scenarios.
Implementation Example
The following Rust code demonstrates the complete lifecycle of the incremental saver:
// 1️⃣ Create a saver and start recording with auto-save enabled
let mut saver = RecordingSaver::new();
saver.set_meeting_name(Some("Team Standup".into()));
let audio_sender = saver.start_accumulation(true); // true → enable incremental audio saver
// 2️⃣ During recording, feed raw audio chunks (produced by the capture pipeline)
audio_sender.send(audio_chunk).unwrap();
// 3️⃣ Add a transcript segment – the saver writes it to disk immediately
saver.add_transcript_segment(TranscriptSegment {
id: "seg_001".into(),
text: "Welcome everyone".into(),
audio_start_time: 0.0,
audio_end_time: 2.1,
duration: 2.1,
display_time: "[00:00]".into(),
confidence: 0.98,
sequence_id: 1,
});
// 4️⃣ When the user stops recording, finalize everything
let final_path = saver.stop_and_save(&app_handle, Some(recording_seconds)).await?;
println!("Saved final audio to {}", final_path.unwrap());
Summary
- RecordingSaver in
recording_saver.rsorchestrates the saving flow, managing meeting folders and transcript persistence. - IncrementalAudioSaver in
incremental_saver.rshandles checkpoint-based audio storage using 48 kHz sample rate configurations. - Atomic file operations via temp-then-rename ensure
metadata.jsonandtranscripts.jsonintegrity during power failures. - Checkpoint files in the
.checkpointssubdirectory provide chunk-level recovery capabilities for audio data. - Graceful finalization merges checkpoints into
audio.mp4only after all chunks are safely persisted to disk.
Frequently Asked Questions
How does Meetily prevent data loss if the application crashes during recording?
Meetily writes each audio chunk to a separate numbered checkpoint file in the .checkpoints directory immediately upon receipt. Because these writes occur before the chunk is acknowledged as processed, already-written checkpoints remain on disk even if the application crashes. When the application restarts, the finalization logic can recover from the last successful checkpoint, ensuring minimal data loss limited to only the most recent unwritten milliseconds.
Where are the incremental checkpoint files stored during a recording?
The checkpoint files are stored in a .checkpoints subdirectory within the meeting folder, located at ~/Library/Application Support/Meetily/recordings/<meeting-name>/ on macOS. This folder structure is created by the create_meeting_folder function in audio_processing.rs when initialize_meeting_folder is called with the create_checkpoints parameter set to true at the start of recording.
What is the difference between auto-save enabled and disabled modes?
When start_accumulation(true) is called, the system instantiates an IncrementalAudioSaver that writes every audio chunk to numbered checkpoint files. When set to false, the audio checkpointing is disabled, but the system continues to persist transcript data to transcripts.json using atomic writes. This mode protects transcription data while eliminating the disk I/O overhead associated with continuous audio checkpointing.
How does Meetily ensure transcript files are not corrupted during writes?
The system uses atomic file replacement operations implemented in recording_saver.rs. Both write_metadata and write_transcripts_json write new content to temporary files first, then use std::fs::rename to atomically replace the existing files. This approach ensures that the original file remains intact until the new content is completely written, preventing corruption from partial writes caused by application crashes or system power loss.
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 →