diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index 82257b593..b6439b1c4 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -33,8 +33,8 @@ use crate::{ sched::timespan::{answer_button_time, learning_congrats, studied_today, time_span}, search::SortMode, sync::{ - sync_login, FullSyncProgress, NormalSyncProgress, SyncActionRequired, SyncAuth, SyncOutput, - SyncStage, + sync_abort, sync_login, FullSyncProgress, NormalSyncProgress, SyncActionRequired, SyncAuth, + SyncOutput, SyncStage, }, template::RenderedNode, text::{extract_av_tags, strip_av_tags, AVTag}, @@ -1258,6 +1258,7 @@ impl Backend { self.sync_abort = Some(abort_handle); let mut rt = Runtime::new().unwrap(); + let input_copy = input.clone(); let ret = self.with_col(|col| { let result = if check_only { @@ -1280,6 +1281,11 @@ impl Backend { // if the user aborted, we'll need to clean up the transaction if !check_only { col.storage.rollback_trx()?; + // and tell AnkiWeb to clean up + let _handle = std::thread::spawn(move || { + let _ = + rt.block_on(sync_abort(input_copy.hkey, input_copy.host_number)); + }); } Err(AnkiError::Interrupted) diff --git a/rslib/src/sync/mod.rs b/rslib/src/sync/mod.rs index 3259ab2d5..d492c142f 100644 --- a/rslib/src/sync/mod.rs +++ b/rslib/src/sync/mod.rs @@ -586,6 +586,11 @@ pub async fn sync_login(username: &str, password: &str) -> Result { }) } +pub async fn sync_abort(hkey: String, host_number: u32) -> Result<()> { + let remote = HTTPSyncClient::new(Some(hkey), host_number); + remote.abort().await +} + impl Collection { pub async fn get_sync_status(&mut self, auth: SyncAuth) -> Result { NormalSyncer::new(self, auth, |_p, _t| ()) @@ -598,7 +603,6 @@ impl Collection { where F: FnMut(NormalSyncProgress, bool), { - // fixme: server abort on failure NormalSyncer::new(self, auth, progress_fn).sync().await }