From 9595101065f25dc02e3256f4977d87953b61c1b1 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 7 Sep 2023 14:10:50 +1000 Subject: [PATCH] Wrap backend in an outer Arc Necessary to allow backend commands that run in the background instead of blocking. --- rslib/src/backend/mod.rs | 37 +++++++++++++++++++++++++------------ rslib/src/backend/sync.rs | 9 +++------ rslib/src/progress.rs | 4 ---- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index 441d35f72..eb611dafd 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -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>>, +#[derive(Clone)] +#[repr(transparent)] +pub struct Backend(Arc); + +impl Deref for Backend { + type Target = BackendInner; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub struct BackendInner { + col: Mutex>, pub(crate) tr: I18n, server: bool, - sync_abort: AbortHandleSlot, + sync_abort: Mutex>, progress_state: Arc>, runtime: OnceCell, - state: Arc>, - backup_task: Arc>>>>, + state: Mutex, + backup_task: Mutex>>>, web_client: OnceCell, } @@ -64,20 +77,20 @@ pub fn init_backend(init_msg: &[u8]) -> result::Result { 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 { diff --git a/rslib/src/backend/sync.rs b/rslib/src/backend/sync.rs index 234c66a84..0e3a345cc 100644 --- a/rslib/src/backend/sync.rs +++ b/rslib/src/backend/sync.rs @@ -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, + scopeguard::ScopeGuard, 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)) } diff --git a/rslib/src/progress.rs b/rslib/src/progress.rs index 25e115d29..644a4d29f 100644 --- a/rslib/src/progress.rs +++ b/rslib/src/progress.rs @@ -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, } -// fixme: this should support multiple abort handles. -pub(crate) type AbortHandleSlot = Arc>>; - #[derive(Clone, Copy, Debug)] pub enum Progress { MediaSync(MediaSyncProgress),