nathan 2 лет назад
Родитель
Сommit
dcf8fd538d

+ 20 - 19
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<String, FlowyError>;
@@ -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(())

+ 1 - 10
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,

+ 9 - 7
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<dyn DatabaseUser>,
   delegate: Arc<dyn DatabaseViewData>,
-  view_editors: Arc<RwLock<RefCountHashMap<Arc<DatabaseViewEditor>>>>,
+  view_editors: Arc<RwLock<HashMap<String, Arc<DatabaseViewEditor>>>>,
   cell_data_cache: AtomicCellDataCache,
 }
 
@@ -40,7 +40,7 @@ impl DatabaseViews {
     cell_data_cache: AtomicCellDataCache,
     block_event_rx: broadcast::Receiver<DatabaseBlockEvent>,
   ) -> FlowyResult<Self> {
-    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<Arc<DatabaseViewEditor>> {
     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<DatabaseBlockEvent>,
-  view_editors: Arc<RwLock<RefCountHashMap<Arc<DatabaseViewEditor>>>>,
+  view_editors: Arc<RwLock<HashMap<String, Arc<DatabaseViewEditor>>>>,
 ) {
   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;
         }
       }

+ 5 - 6
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))]

+ 1 - 1
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");
     }

+ 2 - 2
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;