Sending sync progress
This commit is contained in:
parent
7fb98a471b
commit
b404fc68e8
2 changed files with 60 additions and 3 deletions
|
@ -9,12 +9,12 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::traits::{BaseCalendar, CalDavSource, DavCalendar};
|
use crate::traits::{BaseCalendar, CalDavSource, DavCalendar};
|
||||||
use crate::traits::CompleteCalendar;
|
use crate::traits::CompleteCalendar;
|
||||||
use crate::item::SyncStatus;
|
use crate::item::{ItemId, SyncStatus};
|
||||||
use crate::calendar::CalendarId;
|
use crate::calendar::CalendarId;
|
||||||
|
|
||||||
mod sync_progress;
|
pub mod sync_progress;
|
||||||
use sync_progress::SyncProgress;
|
use sync_progress::SyncProgress;
|
||||||
pub use sync_progress::FeedbackSender;
|
use sync_progress::{FeedbackSender, SyncEvent};
|
||||||
|
|
||||||
/// A data source that combines two `CalDavSource`s, which is able to sync both sources.
|
/// A data source that combines two `CalDavSource`s, which is able to sync both sources.
|
||||||
///
|
///
|
||||||
|
@ -89,11 +89,13 @@ where
|
||||||
if let Err(err) = self.run_sync_inner(progress).await {
|
if let Err(err) = self.run_sync_inner(progress).await {
|
||||||
progress.error(&format!("Sync terminated because of an error: {}", err));
|
progress.error(&format!("Sync terminated because of an error: {}", err));
|
||||||
}
|
}
|
||||||
|
progress.feedback(SyncEvent::Finished{ success: progress.is_success() });
|
||||||
progress.is_success()
|
progress.is_success()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_sync_inner(&mut self, progress: &mut SyncProgress) -> Result<(), Box<dyn Error>> {
|
async fn run_sync_inner(&mut self, progress: &mut SyncProgress) -> Result<(), Box<dyn Error>> {
|
||||||
progress.info("Starting a sync.");
|
progress.info("Starting a sync.");
|
||||||
|
progress.feedback(SyncEvent::Started);
|
||||||
|
|
||||||
let mut handled_calendars = HashSet::new();
|
let mut handled_calendars = HashSet::new();
|
||||||
|
|
||||||
|
@ -151,6 +153,13 @@ where
|
||||||
async fn sync_calendar_pair(cal_local: Arc<Mutex<T>>, cal_remote: Arc<Mutex<U>>, progress: &mut SyncProgress) -> Result<(), Box<dyn Error>> {
|
async fn sync_calendar_pair(cal_local: Arc<Mutex<T>>, cal_remote: Arc<Mutex<U>>, progress: &mut SyncProgress) -> Result<(), Box<dyn Error>> {
|
||||||
let mut cal_remote = cal_remote.lock().unwrap();
|
let mut cal_remote = cal_remote.lock().unwrap();
|
||||||
let mut cal_local = cal_local.lock().unwrap();
|
let mut cal_local = cal_local.lock().unwrap();
|
||||||
|
let cal_name = cal_local.name().to_string();
|
||||||
|
|
||||||
|
progress.info(&format!("Syncing calendar {}", cal_name));
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: "started".to_string()
|
||||||
|
});
|
||||||
|
|
||||||
// Step 1 - find the differences
|
// Step 1 - find the differences
|
||||||
progress.debug("Finding the differences to sync...");
|
progress.debug("Finding the differences to sync...");
|
||||||
|
@ -162,6 +171,11 @@ where
|
||||||
let mut remote_additions = HashSet::new();
|
let mut remote_additions = HashSet::new();
|
||||||
|
|
||||||
let remote_items = cal_remote.get_item_version_tags().await?;
|
let remote_items = cal_remote.get_item_version_tags().await?;
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: format!("{} remote items", remote_items.len()),
|
||||||
|
});
|
||||||
|
|
||||||
let mut local_items_to_handle = cal_local.get_item_ids().await?;
|
let mut local_items_to_handle = cal_local.get_item_ids().await?;
|
||||||
for (id, remote_tag) in remote_items {
|
for (id, remote_tag) in remote_items {
|
||||||
progress.trace(&format!("***** Considering remote item {}...", id));
|
progress.trace(&format!("***** Considering remote item {}...", id));
|
||||||
|
@ -254,6 +268,10 @@ where
|
||||||
progress.trace("Committing changes...");
|
progress.trace("Committing changes...");
|
||||||
for id_del in local_del {
|
for id_del in local_del {
|
||||||
progress.debug(&format!("> Pushing local deletion {} to the server", id_del));
|
progress.debug(&format!("> Pushing local deletion {} to the server", id_del));
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: Self::item_name(&cal_local, &id_del).await,
|
||||||
|
});
|
||||||
match cal_remote.delete_item(&id_del).await {
|
match cal_remote.delete_item(&id_del).await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
progress.warn(&format!("Unable to delete remote item {}: {}", id_del, err));
|
progress.warn(&format!("Unable to delete remote item {}: {}", id_del, err));
|
||||||
|
@ -269,6 +287,10 @@ where
|
||||||
|
|
||||||
for id_del in remote_del {
|
for id_del in remote_del {
|
||||||
progress.debug(&format!("> Applying remote deletion {} locally", id_del));
|
progress.debug(&format!("> Applying remote deletion {} locally", id_del));
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: Self::item_name(&cal_local, &id_del).await,
|
||||||
|
});
|
||||||
if let Err(err) = cal_local.immediately_delete_item(&id_del).await {
|
if let Err(err) = cal_local.immediately_delete_item(&id_del).await {
|
||||||
progress.warn(&format!("Unable to delete local item {}: {}", id_del, err));
|
progress.warn(&format!("Unable to delete local item {}: {}", id_del, err));
|
||||||
}
|
}
|
||||||
|
@ -276,6 +298,10 @@ where
|
||||||
|
|
||||||
for id_add in remote_additions {
|
for id_add in remote_additions {
|
||||||
progress.debug(&format!("> Applying remote addition {} locally", id_add));
|
progress.debug(&format!("> Applying remote addition {} locally", id_add));
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: Self::item_name(&cal_local, &id_add).await,
|
||||||
|
});
|
||||||
match cal_remote.get_item_by_id(&id_add).await {
|
match cal_remote.get_item_by_id(&id_add).await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
progress.warn(&format!("Unable to get remote item {}: {}. Skipping it.", id_add, err));
|
progress.warn(&format!("Unable to get remote item {}: {}. Skipping it.", id_add, err));
|
||||||
|
@ -297,6 +323,10 @@ where
|
||||||
|
|
||||||
for id_change in remote_changes {
|
for id_change in remote_changes {
|
||||||
progress.debug(&format!("> Applying remote change {} locally", id_change));
|
progress.debug(&format!("> Applying remote change {} locally", id_change));
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: Self::item_name(&cal_local, &id_change).await,
|
||||||
|
});
|
||||||
match cal_remote.get_item_by_id(&id_change).await {
|
match cal_remote.get_item_by_id(&id_change).await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
progress.warn(&format!("Unable to get remote item {}: {}. Skipping it", id_change, err));
|
progress.warn(&format!("Unable to get remote item {}: {}. Skipping it", id_change, err));
|
||||||
|
@ -319,6 +349,10 @@ where
|
||||||
|
|
||||||
for id_add in local_additions {
|
for id_add in local_additions {
|
||||||
progress.debug(&format!("> Pushing local addition {} to the server", id_add));
|
progress.debug(&format!("> Pushing local addition {} to the server", id_add));
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: Self::item_name(&cal_local, &id_add).await,
|
||||||
|
});
|
||||||
match cal_local.get_item_by_id_mut(&id_add).await {
|
match cal_local.get_item_by_id_mut(&id_add).await {
|
||||||
None => {
|
None => {
|
||||||
progress.error(&format!("Inconsistency: created item {} has been marked for upload but is locally missing", id_add));
|
progress.error(&format!("Inconsistency: created item {} has been marked for upload but is locally missing", id_add));
|
||||||
|
@ -338,6 +372,10 @@ where
|
||||||
|
|
||||||
for id_change in local_changes {
|
for id_change in local_changes {
|
||||||
progress.debug(&format!("> Pushing local change {} to the server", id_change));
|
progress.debug(&format!("> Pushing local change {} to the server", id_change));
|
||||||
|
progress.feedback(SyncEvent::InProgress{
|
||||||
|
calendar: cal_name.clone(),
|
||||||
|
details: Self::item_name(&cal_local, &id_change).await,
|
||||||
|
});
|
||||||
match cal_local.get_item_by_id_mut(&id_change).await {
|
match cal_local.get_item_by_id_mut(&id_change).await {
|
||||||
None => {
|
None => {
|
||||||
progress.error(&format!("Inconsistency: modified item {} has been marked for upload but is locally missing", id_change));
|
progress.error(&format!("Inconsistency: modified item {} has been marked for upload but is locally missing", id_change));
|
||||||
|
@ -357,6 +395,12 @@ where
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn item_name(cal: &T, id: &ItemId) -> String {
|
||||||
|
cal.get_item_by_id(id).await.map(|item| item.name()).unwrap_or_default().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,21 +64,34 @@ impl SyncProgress {
|
||||||
self.n_errors == 0
|
self.n_errors == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Log an error
|
||||||
pub fn error(&mut self, text: &str) {
|
pub fn error(&mut self, text: &str) {
|
||||||
log::error!("{}", text);
|
log::error!("{}", text);
|
||||||
self.n_errors += 1;
|
self.n_errors += 1;
|
||||||
}
|
}
|
||||||
|
/// Log a warning
|
||||||
pub fn warn(&mut self, text: &str) {
|
pub fn warn(&mut self, text: &str) {
|
||||||
log::warn!("{}", text);
|
log::warn!("{}", text);
|
||||||
self.n_errors += 1;
|
self.n_errors += 1;
|
||||||
}
|
}
|
||||||
|
/// Log an info
|
||||||
pub fn info(&mut self, text: &str) {
|
pub fn info(&mut self, text: &str) {
|
||||||
log::info!("{}", text);
|
log::info!("{}", text);
|
||||||
}
|
}
|
||||||
|
/// Log a debug message
|
||||||
pub fn debug(&mut self, text: &str) {
|
pub fn debug(&mut self, text: &str) {
|
||||||
log::debug!("{}", text);
|
log::debug!("{}", text);
|
||||||
}
|
}
|
||||||
|
/// Log a trace message
|
||||||
pub fn trace(&mut self, text: &str) {
|
pub fn trace(&mut self, text: &str) {
|
||||||
log::trace!("{}", text);
|
log::trace!("{}", text);
|
||||||
}
|
}
|
||||||
|
/// Send an event as a feedback to the listener (if any).
|
||||||
|
pub fn feedback(&mut self, event: SyncEvent) {
|
||||||
|
self.feedback_channel
|
||||||
|
.as_ref()
|
||||||
|
.map(|sender| {
|
||||||
|
sender.send(event)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue