diff --git a/proto/backend.proto b/proto/backend.proto index 331fa5d83..618db0522 100644 --- a/proto/backend.proto +++ b/proto/backend.proto @@ -161,6 +161,7 @@ service BackendService { rpc SyncMedia (SyncAuth) returns (Empty); rpc AbortSync (Empty) returns (Empty); + rpc AbortMediaSync (Empty) returns (Empty); rpc BeforeUpload (Empty) returns (Empty); rpc SyncLogin (SyncLoginIn) returns (SyncAuth); rpc SyncStatus (SyncAuth) returns (SyncCollectionOut); diff --git a/pylib/anki/rsbackend.py b/pylib/anki/rsbackend.py index 3b62e4330..f01aec5ec 100644 --- a/pylib/anki/rsbackend.py +++ b/pylib/anki/rsbackend.py @@ -166,7 +166,7 @@ class ProgressKind(enum.Enum): @dataclass class Progress: kind: ProgressKind - val: Union[MediaSyncProgress, pb.FullSyncProgress, str] + val: Union[MediaSyncProgress, pb.FullSyncProgress, NormalSyncProgress, str] @staticmethod def from_proto(proto: pb.Progress) -> Progress: diff --git a/qt/aqt/mediasync.py b/qt/aqt/mediasync.py index ac2acf4d2..4d9ca3c1a 100644 --- a/qt/aqt/mediasync.py +++ b/qt/aqt/mediasync.py @@ -109,9 +109,8 @@ class MediaSyncer: if not self.is_syncing(): return self._log_and_notify(tr(TR.SYNC_MEDIA_ABORTING)) - # fixme: latter should do the former for us in the future self.mw.col.backend.set_wants_abort() - self.mw.col.backend.abort_sync() + self.mw.col.backend.abort_media_sync() def is_syncing(self) -> bool: return self._syncing diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index da0b07d1a..82257b593 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -89,6 +89,7 @@ pub struct Backend { i18n: I18n, server: bool, sync_abort: Option, + media_sync_abort: Option, progress_state: Arc>, } @@ -1013,6 +1014,13 @@ impl BackendService for Backend { Ok(().into()) } + fn abort_media_sync(&mut self, _input: Empty) -> BackendResult { + if let Some(handle) = self.media_sync_abort.take() { + handle.abort(); + } + Ok(().into()) + } + fn before_upload(&mut self, _input: Empty) -> BackendResult { self.with_col(|col| col.before_upload().map(Into::into)) } @@ -1142,6 +1150,7 @@ impl Backend { i18n, server, sync_abort: None, + media_sync_abort: None, progress_state: Arc::new(Mutex::new(ProgressState { want_abort: false, last_progress: None, @@ -1202,7 +1211,7 @@ impl Backend { log: Logger, ) -> Result<()> { let (abort_handle, abort_reg) = AbortHandle::new_pair(); - self.sync_abort = Some(abort_handle); + self.media_sync_abort = Some(abort_handle); let mut handler = self.new_progress_handler(); let progress_fn = move |progress| handler.update(progress, true); @@ -1218,7 +1227,7 @@ impl Backend { Err(AnkiError::Interrupted) } }; - self.sync_abort = None; + self.media_sync_abort = None; ret } @@ -1267,7 +1276,14 @@ impl Backend { }; match result { Ok(sync_result) => sync_result, - Err(_) => Err(AnkiError::Interrupted), + Err(_) => { + // if the user aborted, we'll need to clean up the transaction + if !check_only { + col.storage.rollback_trx()?; + } + + Err(AnkiError::Interrupted) + } } }); self.sync_abort = None; diff --git a/rspy/src/lib.rs b/rspy/src/lib.rs index f6cb6e9a0..3a132bde8 100644 --- a/rspy/src/lib.rs +++ b/rspy/src/lib.rs @@ -92,6 +92,7 @@ fn want_release_gil(method: u32) -> bool { BackendMethod::OpenCollection => true, BackendMethod::CloseCollection => true, BackendMethod::AbortSync => true, + BackendMethod::AbortMediaSync => true, BackendMethod::BeforeUpload => true, BackendMethod::TranslateString => false, BackendMethod::FormatTimespan => false,