Browse Source

format log and fix duplicate write issue

appflowy 3 years ago
parent
commit
c95fdc4782

+ 2 - 0
frontend/rust-lib/flowy-core/src/controller.rs

@@ -143,6 +143,7 @@ impl FolderManager {
         }
         }
     }
     }
 
 
+    #[tracing::instrument(level = "trace", skip(self), err)]
     pub async fn initialize(&self, user_id: &str, token: &str) -> FlowyResult<()> {
     pub async fn initialize(&self, user_id: &str, token: &str) -> FlowyResult<()> {
         let mut write_guard = INIT_FOLDER_FLAG.write().await;
         let mut write_guard = INIT_FOLDER_FLAG.write().await;
         if let Some(is_init) = write_guard.get(user_id) {
         if let Some(is_init) = write_guard.get(user_id) {
@@ -150,6 +151,7 @@ impl FolderManager {
                 return Ok(());
                 return Ok(());
             }
             }
         }
         }
+        tracing::debug!("Initialize folder editor");
         let folder_id = FolderId::new(user_id);
         let folder_id = FolderId::new(user_id);
         let _ = self.persistence.initialize(user_id, &folder_id).await?;
         let _ = self.persistence.initialize(user_id, &folder_id).await?;
 
 

+ 1 - 0
frontend/rust-lib/flowy-core/src/services/persistence/migration.rs

@@ -62,6 +62,7 @@ impl FolderMigration {
         })?;
         })?;
 
 
         if workspaces.is_empty() {
         if workspaces.is_empty() {
+            KV::set_bool(&key, true);
             return Ok(None);
             return Ok(None);
         }
         }
 
 

+ 1 - 1
frontend/rust-lib/flowy-sdk/src/lib.rs

@@ -235,7 +235,7 @@ async fn _listen_network_status(mut subscribe: broadcast::Receiver<NetworkType>,
 fn init_kv(root: &str) {
 fn init_kv(root: &str) {
     match flowy_database::kv::KV::init(root) {
     match flowy_database::kv::KV::init(root) {
         Ok(_) => {}
         Ok(_) => {}
-        Err(e) => tracing::error!("Init kv store failedL: {}", e),
+        Err(e) => tracing::error!("Init kv store failed: {}", e),
     }
     }
 }
 }
 
 

+ 1 - 6
frontend/rust-lib/flowy-sync/src/cache/disk/mod.rs

@@ -32,12 +32,7 @@ pub trait RevisionDiskCache: Sync + Send {
     fn update_revision_record(&self, changesets: Vec<RevisionChangeset>) -> FlowyResult<()>;
     fn update_revision_record(&self, changesets: Vec<RevisionChangeset>) -> FlowyResult<()>;
 
 
     // Delete all the records if the rev_ids is None
     // Delete all the records if the rev_ids is None
-    fn delete_revision_records(
-        &self,
-        object_id: &str,
-        rev_ids: Option<Vec<i64>>,
-        conn: &SqliteConnection,
-    ) -> Result<(), Self::Error>;
+    fn delete_revision_records(&self, object_id: &str, rev_ids: Option<Vec<i64>>) -> Result<(), Self::Error>;
 
 
     // Delete and insert will be executed in the same transaction.
     // Delete and insert will be executed in the same transaction.
     // It deletes all the records if the deleted_rev_ids is None and then insert the new records
     // It deletes all the records if the deleted_rev_ids is None and then insert the new records

+ 12 - 9
frontend/rust-lib/flowy-sync/src/cache/disk/sql_impl.rs

@@ -62,12 +62,8 @@ impl RevisionDiskCache for SQLitePersistence {
         Ok(())
         Ok(())
     }
     }
 
 
-    fn delete_revision_records(
-        &self,
-        object_id: &str,
-        rev_ids: Option<Vec<i64>>,
-        conn: &SqliteConnection,
-    ) -> Result<(), Self::Error> {
+    fn delete_revision_records(&self, object_id: &str, rev_ids: Option<Vec<i64>>) -> Result<(), Self::Error> {
+        let conn = &*self.pool.get().map_err(internal_error)?;
         let _ = RevisionTableSql::delete(object_id, rev_ids, conn)?;
         let _ = RevisionTableSql::delete(object_id, rev_ids, conn)?;
         Ok(())
         Ok(())
     }
     }
@@ -80,7 +76,7 @@ impl RevisionDiskCache for SQLitePersistence {
     ) -> Result<(), Self::Error> {
     ) -> Result<(), Self::Error> {
         let conn = self.pool.get().map_err(internal_error)?;
         let conn = self.pool.get().map_err(internal_error)?;
         conn.immediate_transaction::<_, FlowyError, _>(|| {
         conn.immediate_transaction::<_, FlowyError, _>(|| {
-            let _ = self.delete_revision_records(object_id, deleted_rev_ids, &*conn)?;
+            let _ = RevisionTableSql::delete(object_id, deleted_rev_ids, &*conn)?;
             let _ = self.create_revision_records(inserted_records, &*conn)?;
             let _ = self.create_revision_records(inserted_records, &*conn)?;
             Ok(())
             Ok(())
         })
         })
@@ -105,6 +101,11 @@ impl RevisionTableSql {
         let records = revision_records
         let records = revision_records
             .into_iter()
             .into_iter()
             .map(|record| {
             .map(|record| {
+                tracing::trace!(
+                    "[RevisionTable] create revision: {}:{:?}",
+                    record.revision.object_id,
+                    record.revision.rev_id
+                );
                 let rev_state: RevisionTableState = record.state.into();
                 let rev_state: RevisionTableState = record.state.into();
                 (
                 (
                     dsl::doc_id.eq(record.revision.object_id),
                     dsl::doc_id.eq(record.revision.object_id),
@@ -178,9 +179,11 @@ impl RevisionTableSql {
         rev_ids: Option<Vec<i64>>,
         rev_ids: Option<Vec<i64>>,
         conn: &SqliteConnection,
         conn: &SqliteConnection,
     ) -> Result<(), FlowyError> {
     ) -> Result<(), FlowyError> {
-        let filter = dsl::rev_table.filter(dsl::doc_id.eq(object_id));
-        let mut sql = diesel::delete(filter).into_boxed();
+        let mut sql = diesel::delete(dsl::rev_table).into_boxed();
+        sql = sql.filter(dsl::doc_id.eq(object_id));
+
         if let Some(rev_ids) = rev_ids {
         if let Some(rev_ids) = rev_ids {
+            tracing::trace!("[RevisionTable] Delete revision: {}:{:?}", object_id, rev_ids);
             sql = sql.filter(dsl::rev_id.eq_any(rev_ids));
             sql = sql.filter(dsl::rev_id.eq_any(rev_ids));
         }
         }
 
 

+ 4 - 2
frontend/rust-lib/flowy-sync/src/cache/memory.rs

@@ -42,8 +42,10 @@ impl RevisionMemoryCache {
         let rev_id = record.revision.rev_id;
         let rev_id = record.revision.rev_id;
         self.revs_map.insert(rev_id, record);
         self.revs_map.insert(rev_id, record);
 
 
-        if !self.pending_write_revs.read().await.contains(&rev_id) {
-            self.pending_write_revs.write().await.push(rev_id);
+        let mut write_guard = self.pending_write_revs.write().await;
+        if !write_guard.contains(&rev_id) {
+            write_guard.push(rev_id);
+            drop(write_guard);
             self.make_checkpoint().await;
             self.make_checkpoint().await;
         }
         }
     }
     }

+ 6 - 12
frontend/rust-lib/flowy-sync/src/cache/mod.rs

@@ -42,7 +42,8 @@ impl RevisionCache {
 
 
     pub async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> {
     pub async fn add(&self, revision: Revision, state: RevisionState, write_to_disk: bool) -> FlowyResult<()> {
         if self.memory_cache.contains(&revision.rev_id) {
         if self.memory_cache.contains(&revision.rev_id) {
-            return Err(FlowyError::internal().context(format!("Duplicate revision: {} {:?}", revision.rev_id, state)));
+            tracing::warn!("Duplicate revision: {}:{}-{:?}", self.object_id, revision.rev_id, state);
+            return Ok(());
         }
         }
         let rev_id = revision.rev_id;
         let rev_id = revision.rev_id;
         let record = RevisionRecord {
         let record = RevisionRecord {
@@ -58,19 +59,12 @@ impl RevisionCache {
 
 
     pub async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> {
     pub async fn compact(&self, range: &RevisionRange, new_revision: Revision) -> FlowyResult<()> {
         self.memory_cache.remove_with_range(range);
         self.memory_cache.remove_with_range(range);
-        let rev_id = new_revision.rev_id;
-        let record = RevisionRecord {
-            revision: new_revision,
-            state: RevisionState::Sync,
-            write_to_disk: true,
-        };
-
         let rev_ids = range.to_rev_ids();
         let rev_ids = range.to_rev_ids();
         let _ = self
         let _ = self
             .disk_cache
             .disk_cache
-            .delete_and_insert_records(&self.object_id, Some(rev_ids), vec![record.clone()])?;
-        self.memory_cache.add(Cow::Owned(record)).await;
-        self.set_latest_rev_id(rev_id);
+            .delete_revision_records(&self.object_id, Some(rev_ids))?;
+
+        self.add(new_revision, RevisionState::Sync, true).await?;
         Ok(())
         Ok(())
     }
     }
 
 
@@ -120,7 +114,7 @@ impl RevisionCache {
                 //     let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap();
                 //     let delta = PlainDelta::from_bytes(&record.revision.delta_data).unwrap();
                 //     tracing::trace!("{}", delta.to_string());
                 //     tracing::trace!("{}", delta.to_string());
                 // });
                 // });
-                tracing::error!("Revisions len is not equal to range required");
+                tracing::error!("Expect revision len {},but receive {}", range_len, records.len());
             }
             }
         }
         }
         Ok(records
         Ok(records

+ 8 - 1
frontend/rust-lib/flowy-sync/src/rev_manager.rs

@@ -171,17 +171,24 @@ impl RevisionCacheCompact {
         }
         }
     }
     }
 
 
+    // Call this method to write the revisions that fetch from server to disk.
+    #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, object_id=%self.object_id), err)]
     async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> {
     async fn add_ack_revision(&self, revision: &Revision) -> FlowyResult<()> {
+        tracing::Span::current().record("rev_id", &revision.rev_id);
         self.inner.add(revision.clone(), RevisionState::Ack, true).await
         self.inner.add(revision.clone(), RevisionState::Ack, true).await
     }
     }
 
 
+    // Call this method to sync the revisions that already in local db.
+    #[tracing::instrument(level = "trace", skip(self), fields(rev_id, object_id=%self.object_id), err)]
     async fn add_sync_revision(&mut self, revision: &Revision) -> FlowyResult<()> {
     async fn add_sync_revision(&mut self, revision: &Revision) -> FlowyResult<()> {
+        tracing::Span::current().record("rev_id", &revision.rev_id);
         self.inner.add(revision.clone(), RevisionState::Sync, false).await?;
         self.inner.add(revision.clone(), RevisionState::Sync, false).await?;
         self.sync_seq.add(revision.rev_id)?;
         self.sync_seq.add(revision.rev_id)?;
         Ok(())
         Ok(())
     }
     }
 
 
-    #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range), err)]
+    // Call this method to save the new revisions generated by the user input.
+    #[tracing::instrument(level = "trace", skip(self, revision), fields(rev_id, compact_range, object_id=%self.object_id), err)]
     async fn write_sync_revision<C>(&mut self, revision: &Revision) -> FlowyResult<i64>
     async fn write_sync_revision<C>(&mut self, revision: &Revision) -> FlowyResult<i64>
     where
     where
         C: RevisionCompact,
         C: RevisionCompact,