mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 15:32:23 -04:00
handle aborting normal sync
- Use a separate abort handle, as the media sync is running in the background and we need to be able to target them separately. The current progress handling is going to need a rethink if we introduce any other background tasks in the future. - Roll back the transaction when interrupting.
This commit is contained in:
parent
c6f0710ce7
commit
90e19daec2
5 changed files with 23 additions and 6 deletions
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -89,6 +89,7 @@ pub struct Backend {
|
|||
i18n: I18n,
|
||||
server: bool,
|
||||
sync_abort: Option<AbortHandle>,
|
||||
media_sync_abort: Option<AbortHandle>,
|
||||
progress_state: Arc<Mutex<ProgressState>>,
|
||||
}
|
||||
|
||||
|
@ -1013,6 +1014,13 @@ impl BackendService for Backend {
|
|||
Ok(().into())
|
||||
}
|
||||
|
||||
fn abort_media_sync(&mut self, _input: Empty) -> BackendResult<Empty> {
|
||||
if let Some(handle) = self.media_sync_abort.take() {
|
||||
handle.abort();
|
||||
}
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
fn before_upload(&mut self, _input: Empty) -> BackendResult<Empty> {
|
||||
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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue