Wrap backend in an outer Arc

Necessary to allow backend commands that run in the background instead
of blocking.
This commit is contained in:
Damien Elmes 2023-09-07 14:10:50 +10:00
parent ffd392de21
commit 9595101065
3 changed files with 28 additions and 22 deletions

View File

@ -14,11 +14,13 @@ mod import_export;
mod ops;
mod sync;
use std::ops::Deref;
use std::result;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread::JoinHandle;
use futures::future::AbortHandle;
use once_cell::sync::OnceCell;
use prost::Message;
use reqwest::Client;
@ -28,20 +30,31 @@ use tokio::runtime::Runtime;
use crate::backend::dbproxy::db_command_bytes;
use crate::backend::sync::SyncState;
use crate::prelude::*;
use crate::progress::AbortHandleSlot;
use crate::progress::Progress;
use crate::progress::ProgressState;
use crate::progress::ThrottlingProgressHandler;
pub struct Backend {
col: Arc<Mutex<Option<Collection>>>,
#[derive(Clone)]
#[repr(transparent)]
pub struct Backend(Arc<BackendInner>);
impl Deref for Backend {
type Target = BackendInner;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub struct BackendInner {
col: Mutex<Option<Collection>>,
pub(crate) tr: I18n,
server: bool,
sync_abort: AbortHandleSlot,
sync_abort: Mutex<Option<AbortHandle>>,
progress_state: Arc<Mutex<ProgressState>>,
runtime: OnceCell<Runtime>,
state: Arc<Mutex<BackendState>>,
backup_task: Arc<Mutex<Option<JoinHandle<Result<()>>>>>,
state: Mutex<BackendState>,
backup_task: Mutex<Option<JoinHandle<Result<()>>>>,
web_client: OnceCell<Client>,
}
@ -64,20 +77,20 @@ pub fn init_backend(init_msg: &[u8]) -> result::Result<Backend, String> {
impl Backend {
pub fn new(tr: I18n, server: bool) -> Backend {
Backend {
col: Arc::new(Mutex::new(None)),
Backend(Arc::new(BackendInner {
col: Mutex::new(None),
tr,
server,
sync_abort: Arc::new(Mutex::new(None)),
sync_abort: Mutex::new(None),
progress_state: Arc::new(Mutex::new(ProgressState {
want_abort: false,
last_progress: None,
})),
runtime: OnceCell::new(),
state: Arc::new(Mutex::new(BackendState::default())),
backup_task: Arc::new(Mutex::new(None)),
state: Mutex::new(BackendState::default()),
backup_task: Mutex::new(None),
web_client: OnceCell::new(),
}
}))
}
pub fn i18n(&self) -> &I18n {

View File

@ -1,8 +1,6 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use std::sync::Arc;
use anki_proto::sync::sync_status_response::Required;
use anki_proto::sync::SyncStatusResponse;
use futures::future::AbortHandle;
@ -13,7 +11,6 @@ use tracing::warn;
use super::Backend;
use crate::prelude::*;
use crate::progress::AbortHandleSlot;
use crate::sync::collection::normal::ClientSyncState;
use crate::sync::collection::normal::SyncActionRequired;
use crate::sync::collection::normal::SyncOutput;
@ -154,7 +151,7 @@ impl Backend {
fn sync_abort_handle(
&self,
) -> Result<(
scopeguard::ScopeGuard<AbortHandleSlot, impl FnOnce(AbortHandleSlot)>,
scopeguard::ScopeGuard<Backend, impl FnOnce(Backend)>,
AbortRegistration,
)> {
let (abort_handle, abort_reg) = AbortHandle::new_pair();
@ -171,8 +168,8 @@ impl Backend {
);
}
// Clear the abort handle after the caller is done and drops the guard.
let guard = scopeguard::guard(Arc::clone(&self.sync_abort), |sync_abort| {
sync_abort.lock().unwrap().take();
let guard = scopeguard::guard(self.clone(), |backend| {
backend.sync_abort.lock().unwrap().take();
});
Ok((guard, abort_reg))
}

View File

@ -8,7 +8,6 @@ use std::sync::Mutex;
use anki_i18n::I18n;
use anki_proto::collection::progress::ComputeRetention;
use anki_proto::collection::progress::ComputeWeights;
use futures::future::AbortHandle;
use crate::dbcheck::DatabaseCheckProgress;
use crate::error::AnkiError;
@ -123,9 +122,6 @@ pub struct ProgressState {
pub last_progress: Option<Progress>,
}
// fixme: this should support multiple abort handles.
pub(crate) type AbortHandleSlot = Arc<Mutex<Option<AbortHandle>>>;
#[derive(Clone, Copy, Debug)]
pub enum Progress {
MediaSync(MediaSyncProgress),