mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
allow aborting a media sync while http req in flight
The progress handling code needs a rethink, as we now have two separate ways to flag that the media sync should abort. In the future, it may make sense to switch to polling the backend for progress, instead of passing a callback in.
This commit is contained in:
parent
cb5b122c7c
commit
c9da4bc1a6
5 changed files with 36 additions and 5 deletions
|
@ -55,6 +55,7 @@ message BackendInput {
|
||||||
Empty all_deck_config = 43;
|
Empty all_deck_config = 43;
|
||||||
Empty new_deck_config = 44;
|
Empty new_deck_config = 44;
|
||||||
int64 remove_deck_config = 45;
|
int64 remove_deck_config = 45;
|
||||||
|
Empty abort_media_sync = 46;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ message BackendOutput {
|
||||||
string format_time_span = 31;
|
string format_time_span = 31;
|
||||||
string studied_today = 32;
|
string studied_today = 32;
|
||||||
string congrats_learn_msg = 33;
|
string congrats_learn_msg = 33;
|
||||||
|
Empty abort_media_sync = 46;
|
||||||
|
|
||||||
// fallible commands
|
// fallible commands
|
||||||
TemplateRequirementsOut template_requirements = 16;
|
TemplateRequirementsOut template_requirements = 16;
|
||||||
|
|
|
@ -519,6 +519,9 @@ class RustBackend:
|
||||||
def remove_deck_config(self, dcid: int) -> None:
|
def remove_deck_config(self, dcid: int) -> None:
|
||||||
self._run_command(pb.BackendInput(remove_deck_config=dcid))
|
self._run_command(pb.BackendInput(remove_deck_config=dcid))
|
||||||
|
|
||||||
|
def abort_media_sync(self):
|
||||||
|
self._run_command(pb.BackendInput(abort_media_sync=pb.Empty()))
|
||||||
|
|
||||||
|
|
||||||
def translate_string_in(
|
def translate_string_in(
|
||||||
key: TR, **kwargs: Union[str, int, float]
|
key: TR, **kwargs: Union[str, int, float]
|
||||||
|
|
|
@ -123,6 +123,7 @@ class MediaSyncer:
|
||||||
return
|
return
|
||||||
self._log_and_notify(tr(TR.SYNC_MEDIA_ABORTING))
|
self._log_and_notify(tr(TR.SYNC_MEDIA_ABORTING))
|
||||||
self._want_stop = True
|
self._want_stop = True
|
||||||
|
self.mw.col.backend.abort_media_sync()
|
||||||
|
|
||||||
def is_syncing(self) -> bool:
|
def is_syncing(self) -> bool:
|
||||||
return self._syncing
|
return self._syncing
|
||||||
|
|
|
@ -39,6 +39,7 @@ slog-envlogger = "2.2.0"
|
||||||
serde_repr = "0.1.5"
|
serde_repr = "0.1.5"
|
||||||
num_enum = "0.4.2"
|
num_enum = "0.4.2"
|
||||||
unicase = "2.6.0"
|
unicase = "2.6.0"
|
||||||
|
futures = "0.3.4"
|
||||||
|
|
||||||
# pinned until rusqlite 0.22 comes out
|
# pinned until rusqlite 0.22 comes out
|
||||||
[target.'cfg(target_vendor="apple")'.dependencies.rusqlite]
|
[target.'cfg(target_vendor="apple")'.dependencies.rusqlite]
|
||||||
|
|
|
@ -30,6 +30,7 @@ use crate::timestamp::TimestampSecs;
|
||||||
use crate::types::Usn;
|
use crate::types::Usn;
|
||||||
use crate::{backend_proto as pb, log};
|
use crate::{backend_proto as pb, log};
|
||||||
use fluent::FluentValue;
|
use fluent::FluentValue;
|
||||||
|
use futures::future::{AbortHandle, Abortable};
|
||||||
use log::error;
|
use log::error;
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
@ -47,6 +48,7 @@ pub struct Backend {
|
||||||
progress_callback: Option<ProtoProgressCallback>,
|
progress_callback: Option<ProtoProgressCallback>,
|
||||||
i18n: I18n,
|
i18n: I18n,
|
||||||
server: bool,
|
server: bool,
|
||||||
|
media_sync_abort: Option<AbortHandle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Progress<'a> {
|
enum Progress<'a> {
|
||||||
|
@ -135,6 +137,7 @@ impl Backend {
|
||||||
progress_callback: None,
|
progress_callback: None,
|
||||||
i18n,
|
i18n,
|
||||||
server,
|
server,
|
||||||
|
media_sync_abort: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +277,10 @@ impl Backend {
|
||||||
self.remove_deck_config(dcid)?;
|
self.remove_deck_config(dcid)?;
|
||||||
OValue::RemoveDeckConfig(pb::Empty {})
|
OValue::RemoveDeckConfig(pb::Empty {})
|
||||||
}
|
}
|
||||||
|
Value::AbortMediaSync(_) => {
|
||||||
|
self.abort_media_sync();
|
||||||
|
OValue::AbortMediaSync(pb::Empty {})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,9 +488,7 @@ impl Backend {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixme: will block other db access
|
fn sync_media(&mut self, input: SyncMediaIn) -> Result<()> {
|
||||||
|
|
||||||
fn sync_media(&self, input: SyncMediaIn) -> Result<()> {
|
|
||||||
let mut guard = self.col.lock().unwrap();
|
let mut guard = self.col.lock().unwrap();
|
||||||
|
|
||||||
let col = guard.as_mut().unwrap();
|
let col = guard.as_mut().unwrap();
|
||||||
|
@ -503,19 +508,38 @@ impl Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_media_inner(
|
fn sync_media_inner(
|
||||||
&self,
|
&mut self,
|
||||||
input: pb::SyncMediaIn,
|
input: pb::SyncMediaIn,
|
||||||
folder: PathBuf,
|
folder: PathBuf,
|
||||||
db: PathBuf,
|
db: PathBuf,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let (abort_handle, abort_reg) = AbortHandle::new_pair();
|
||||||
|
self.media_sync_abort = Some(abort_handle);
|
||||||
|
|
||||||
let callback = |progress: &MediaSyncProgress| {
|
let callback = |progress: &MediaSyncProgress| {
|
||||||
self.fire_progress_callback(Progress::MediaSync(progress))
|
self.fire_progress_callback(Progress::MediaSync(progress))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mgr = MediaManager::new(&folder, &db)?;
|
let mgr = MediaManager::new(&folder, &db)?;
|
||||||
let mut rt = Runtime::new().unwrap();
|
let mut rt = Runtime::new().unwrap();
|
||||||
rt.block_on(mgr.sync_media(callback, &input.endpoint, &input.hkey, log))
|
let sync_fut = mgr.sync_media(callback, &input.endpoint, &input.hkey, log);
|
||||||
|
let abortable_sync = Abortable::new(sync_fut, abort_reg);
|
||||||
|
let ret = match rt.block_on(abortable_sync) {
|
||||||
|
Ok(sync_result) => sync_result,
|
||||||
|
Err(_) => {
|
||||||
|
// aborted sync
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.media_sync_abort = None;
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn abort_media_sync(&mut self) {
|
||||||
|
if let Some(handle) = self.media_sync_abort.take() {
|
||||||
|
handle.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_media(&self) -> Result<pb::MediaCheckOut> {
|
fn check_media(&self) -> Result<pb::MediaCheckOut> {
|
||||||
|
|
Loading…
Reference in a new issue