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:
Damien Elmes 2020-04-01 09:49:25 +10:00
parent cb5b122c7c
commit c9da4bc1a6
5 changed files with 36 additions and 5 deletions

View file

@ -55,6 +55,7 @@ message BackendInput {
Empty all_deck_config = 43;
Empty new_deck_config = 44;
int64 remove_deck_config = 45;
Empty abort_media_sync = 46;
}
}
@ -70,6 +71,7 @@ message BackendOutput {
string format_time_span = 31;
string studied_today = 32;
string congrats_learn_msg = 33;
Empty abort_media_sync = 46;
// fallible commands
TemplateRequirementsOut template_requirements = 16;

View file

@ -519,6 +519,9 @@ class RustBackend:
def remove_deck_config(self, dcid: int) -> None:
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(
key: TR, **kwargs: Union[str, int, float]

View file

@ -123,6 +123,7 @@ class MediaSyncer:
return
self._log_and_notify(tr(TR.SYNC_MEDIA_ABORTING))
self._want_stop = True
self.mw.col.backend.abort_media_sync()
def is_syncing(self) -> bool:
return self._syncing

View file

@ -39,6 +39,7 @@ slog-envlogger = "2.2.0"
serde_repr = "0.1.5"
num_enum = "0.4.2"
unicase = "2.6.0"
futures = "0.3.4"
# pinned until rusqlite 0.22 comes out
[target.'cfg(target_vendor="apple")'.dependencies.rusqlite]

View file

@ -30,6 +30,7 @@ use crate::timestamp::TimestampSecs;
use crate::types::Usn;
use crate::{backend_proto as pb, log};
use fluent::FluentValue;
use futures::future::{AbortHandle, Abortable};
use log::error;
use prost::Message;
use std::collections::{HashMap, HashSet};
@ -47,6 +48,7 @@ pub struct Backend {
progress_callback: Option<ProtoProgressCallback>,
i18n: I18n,
server: bool,
media_sync_abort: Option<AbortHandle>,
}
enum Progress<'a> {
@ -135,6 +137,7 @@ impl Backend {
progress_callback: None,
i18n,
server,
media_sync_abort: None,
}
}
@ -274,6 +277,10 @@ impl Backend {
self.remove_deck_config(dcid)?;
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(&self, input: SyncMediaIn) -> Result<()> {
fn sync_media(&mut self, input: SyncMediaIn) -> Result<()> {
let mut guard = self.col.lock().unwrap();
let col = guard.as_mut().unwrap();
@ -503,19 +508,38 @@ impl Backend {
}
fn sync_media_inner(
&self,
&mut self,
input: pb::SyncMediaIn,
folder: PathBuf,
db: PathBuf,
log: Logger,
) -> Result<()> {
let (abort_handle, abort_reg) = AbortHandle::new_pair();
self.media_sync_abort = Some(abort_handle);
let callback = |progress: &MediaSyncProgress| {
self.fire_progress_callback(Progress::MediaSync(progress))
};
let mgr = MediaManager::new(&folder, &db)?;
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> {