diff --git a/frontend/rust-lib/flowy-database/src/manager.rs b/frontend/rust-lib/flowy-database/src/manager.rs index 5195f567de..db0d894efe 100644 --- a/frontend/rust-lib/flowy-database/src/manager.rs +++ b/frontend/rust-lib/flowy-database/src/manager.rs @@ -31,7 +31,7 @@ use flowy_task::TaskDispatcher; use revision_model::Revision; use std::sync::Arc; -use tokio::sync::{RwLock, RwLockWriteGuard, TryLockError}; +use tokio::sync::RwLock; pub trait DatabaseUser: Send + Sync { fn user_id(&self) -> Result; @@ -146,24 +146,25 @@ impl DatabaseManager { let database_info = self.database_ref_indexer.get_database_with_view(view_id)?; tracing::Span::current().record("database_id", &database_info.database_id); - match self.editors_by_database_id.try_write() { - Ok(mut write_guard) => { - if let Some(database_editor) = write_guard.remove(&database_info.database_id) { - database_editor.close_view_editor(view_id).await; - if database_editor.number_of_ref_views().await == 0 { - database_editor.dispose().await; - } else { - self - .editors_by_database_id - .write() - .await - .insert(database_info.database_id, database_editor); - } - } - }, - Err(_) => { - tracing::error!("Try to get the lock of editors_by_database_id failed"); - }, + // Create a temporary reference database_editor in case of holding the write lock + // of editors_by_database_id too long. + let database_editor = self + .editors_by_database_id + .write() + .await + .remove(&database_info.database_id); + + if let Some(database_editor) = database_editor { + database_editor.close_view_editor(view_id).await; + if database_editor.number_of_ref_views().await == 0 { + database_editor.dispose().await; + } else { + self + .editors_by_database_id + .write() + .await + .insert(database_info.database_id, database_editor); + } } Ok(()) diff --git a/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs b/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs index e6918b9f50..96dd993e6c 100644 --- a/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs +++ b/frontend/rust-lib/flowy-database/src/services/database_view/editor.rs @@ -28,9 +28,7 @@ use flowy_error::FlowyResult; use flowy_revision::RevisionManager; use flowy_sqlite::ConnectionPool; use flowy_task::TaskDispatcher; -use lib_infra::async_trait::async_trait; use lib_infra::future::Fut; -use lib_infra::ref_map::RefCountValue; use nanoid::nanoid; use revision_model::Revision; use std::borrow::Cow; @@ -182,8 +180,8 @@ impl DatabaseViewEditor { pub async fn close(&self) { self.rev_manager.generate_snapshot().await; self.rev_manager.close().await; - self.filter_controller.close().await; self.sort_controller.write().await.close().await; + // self.filter_controller.close().await; } pub async fn handle_block_event(&self, event: Cow<'_, DatabaseBlockEvent>) { @@ -869,13 +867,6 @@ pub(crate) async fn get_cells_for_field( Ok(cells) } -#[async_trait] -impl RefCountValue for DatabaseViewEditor { - async fn did_remove(&self) { - self.close().await; - } -} - async fn new_group_controller( user_id: String, view_id: String, diff --git a/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs b/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs index 05975b1fb2..70881b4593 100644 --- a/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs +++ b/frontend/rust-lib/flowy-database/src/services/database_view/editor_manager.rs @@ -20,8 +20,8 @@ use flowy_error::FlowyResult; use flowy_revision::{RevisionManager, RevisionPersistence, RevisionPersistenceConfiguration}; use flowy_sqlite::ConnectionPool; use lib_infra::future::Fut; -use lib_infra::ref_map::RefCountHashMap; use std::borrow::Cow; +use std::collections::HashMap; use std::sync::Arc; use tokio::sync::{broadcast, RwLock}; @@ -29,7 +29,7 @@ use tokio::sync::{broadcast, RwLock}; pub struct DatabaseViews { user: Arc, delegate: Arc, - view_editors: Arc>>>, + view_editors: Arc>>>, cell_data_cache: AtomicCellDataCache, } @@ -40,7 +40,7 @@ impl DatabaseViews { cell_data_cache: AtomicCellDataCache, block_event_rx: broadcast::Receiver, ) -> FlowyResult { - let view_editors = Arc::new(RwLock::new(RefCountHashMap::default())); + let view_editors = Arc::new(RwLock::new(HashMap::default())); listen_on_database_block_event(block_event_rx, view_editors.clone()); Ok(Self { user, @@ -61,7 +61,9 @@ impl DatabaseViews { pub async fn close(&self, view_id: &str) { if let Ok(mut view_editors) = self.view_editors.try_write() { - view_editors.remove(view_id).await; + if let Some(view_editor) = view_editors.remove(view_id) { + view_editor.close().await; + } } else { tracing::error!("Try to get the lock of view_editors failed"); } @@ -273,7 +275,7 @@ impl DatabaseViews { pub async fn get_view_editor(&self, view_id: &str) -> FlowyResult> { debug_assert!(!view_id.is_empty()); if let Some(editor) = self.view_editors.read().await.get(view_id) { - return Ok(editor); + return Ok(editor.clone()); } tracing::trace!("{:p} create view:{} editor", self, view_id); @@ -346,7 +348,7 @@ pub async fn make_database_view_rev_manager( fn listen_on_database_block_event( mut block_event_rx: broadcast::Receiver, - view_editors: Arc>>>, + view_editors: Arc>>>, ) { tokio::spawn(async move { loop { @@ -358,7 +360,7 @@ fn listen_on_database_block_event( } else { Cow::Borrowed(&event) }; - for view_editor in view_editors.iter() { + for view_editor in view_editors { view_editor.handle_block_event(event.clone()).await; } } diff --git a/frontend/rust-lib/flowy-database/src/services/filter/controller.rs b/frontend/rust-lib/flowy-database/src/services/filter/controller.rs index aa0394e03d..0258d3b7b6 100644 --- a/frontend/rust-lib/flowy-database/src/services/filter/controller.rs +++ b/frontend/rust-lib/flowy-database/src/services/filter/controller.rs @@ -74,12 +74,11 @@ impl FilterController { } pub async fn close(&self) { - self - .task_scheduler - .write() - .await - .unregister_handler(&self.handler_id) - .await; + if let Ok(mut task_scheduler) = self.task_scheduler.try_write() { + task_scheduler.unregister_handler(&self.handler_id).await; + } else { + tracing::error!("Try to get the lock of task_scheduler failed"); + } } #[tracing::instrument(name = "schedule_filter_task", level = "trace", skip(self))] diff --git a/frontend/rust-lib/flowy-database/src/services/sort/controller.rs b/frontend/rust-lib/flowy-database/src/services/sort/controller.rs index ab6ac9b721..2abc7d517c 100644 --- a/frontend/rust-lib/flowy-database/src/services/sort/controller.rs +++ b/frontend/rust-lib/flowy-database/src/services/sort/controller.rs @@ -64,7 +64,7 @@ impl SortController { pub async fn close(&self) { if let Ok(mut task_scheduler) = self.task_scheduler.try_write() { - // task_scheduler.unregister_handler(&self.handler_id).await; + task_scheduler.unregister_handler(&self.handler_id).await; } else { tracing::error!("Try to get the lock of task_scheduler failed"); } diff --git a/frontend/rust-lib/flowy-task/src/scheduler.rs b/frontend/rust-lib/flowy-task/src/scheduler.rs index ae61bb08bb..5e24114d3f 100644 --- a/frontend/rust-lib/flowy-task/src/scheduler.rs +++ b/frontend/rust-lib/flowy-task/src/scheduler.rs @@ -2,9 +2,9 @@ use crate::queue::TaskQueue; use crate::store::TaskStore; use crate::{Task, TaskContent, TaskId, TaskState}; use anyhow::Error; -use lib_infra::async_trait::async_trait; + use lib_infra::future::BoxResultFuture; -use lib_infra::ref_map::{RefCountHashMap, RefCountValue}; + use std::collections::HashMap; use std::sync::Arc; use std::time::Duration;