chore: fix database row sync (#4964)

* chore: fix database row sync

* ci: fix test

* ci: fix web build

* chore: bump collab
This commit is contained in:
Nathan.fooo 2024-03-23 09:18:47 +08:00 committed by GitHub
parent c0642d3ff3
commit b307312a71
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 364 additions and 347 deletions

View File

@ -838,7 +838,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-trait",
@ -862,7 +862,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-trait",
@ -892,7 +892,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"collab",
@ -911,7 +911,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"bytes",
@ -926,7 +926,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"chrono",
@ -952,6 +952,7 @@ dependencies = [
"collab",
"collab-entity",
"collab-plugins",
"futures",
"lib-infra",
"parking_lot 0.12.1",
"serde",
@ -963,7 +964,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-stream",
@ -1002,7 +1003,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"collab",

View File

@ -96,10 +96,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9
# To switch to the local path, run:
# scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }

View File

@ -636,7 +636,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-trait",
@ -660,7 +660,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"collab",
@ -679,7 +679,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"bytes",
@ -694,7 +694,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"chrono",
@ -720,6 +720,7 @@ dependencies = [
"collab",
"collab-entity",
"collab-plugins",
"futures",
"lib-infra",
"parking_lot 0.12.1",
"serde",
@ -731,7 +732,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-stream",
@ -769,7 +770,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"collab",
@ -5025,4 +5026,4 @@ dependencies = [
[[patch.unused]]
name = "collab-database"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=0970b2e1440134af7c83bb8fc80cac5d2dedebb7#0970b2e1440134af7c83bb8fc80cac5d2dedebb7"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"

View File

@ -65,10 +65,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9
# To switch to the local path, run:
# scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }

View File

@ -2,7 +2,7 @@ use crate::authenticate_user::AuthenticateUser;
use crate::define::{user_profile_key, user_workspace_key, AF_USER_SESSION_KEY};
use af_persistence::store::{AppFlowyWASMStore, IndexddbStore};
use anyhow::Context;
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab_entity::CollabType;
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
use collab_integrate::{CollabKVDB, MutexCollab};
@ -200,7 +200,7 @@ impl UserManager {
&self,
session: &Session,
collab_db: Weak<CollabKVDB>,
raw_data: CollabDocState,
raw_data: Vec<u8>,
) -> Result<Arc<MutexCollab>, FlowyError> {
let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new(
ErrorCode::Internal,
@ -212,7 +212,7 @@ impl UserManager {
session.user_id,
&user_awareness_id.to_string(),
CollabType::UserAwareness,
raw_data,
DocStateSource::FromDocState(raw_data),
collab_db,
CollabBuilderConfig::default().sync_enable(true),
)

View File

@ -55,8 +55,8 @@ impl CollabCloudPluginProvider for ServerProviderWASM {
CollabPluginProviderType::AppFlowyCloud
}
fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> {
to_fut(async move { vec![] })
fn get_plugins(&self, _context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
vec![]
}
fn is_sync_enabled(&self) -> bool {

View File

@ -764,7 +764,7 @@ dependencies = [
[[package]]
name = "collab"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-trait",
@ -788,7 +788,7 @@ dependencies = [
[[package]]
name = "collab-database"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-trait",
@ -818,7 +818,7 @@ dependencies = [
[[package]]
name = "collab-document"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"collab",
@ -837,7 +837,7 @@ dependencies = [
[[package]]
name = "collab-entity"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"bytes",
@ -852,7 +852,7 @@ dependencies = [
[[package]]
name = "collab-folder"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"chrono",
@ -878,6 +878,7 @@ dependencies = [
"collab",
"collab-entity",
"collab-plugins",
"futures",
"lib-infra",
"parking_lot 0.12.1",
"serde",
@ -889,7 +890,7 @@ dependencies = [
[[package]]
name = "collab-plugins"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"async-stream",
@ -928,7 +929,7 @@ dependencies = [
[[package]]
name = "collab-user"
version = "0.1.0"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=25c4be5#25c4be5d60fa67f0d2de7f69cc8292a4506e07de"
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=79be7f4c6e8e672b6f08ffda866876c01fc28e62#79be7f4c6e8e672b6f08ffda866876c01fc28e62"
dependencies = [
"anyhow",
"collab",

View File

@ -120,10 +120,10 @@ client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "ab9
# To switch to the local path, run:
# scripts/tool/update_collab_source.sh
# ⚠️⚠️⚠️️
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "25c4be5" }
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-folder = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-database = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-plugins = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-user = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }
collab-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "79be7f4c6e8e672b6f08ffda866876c01fc28e62" }

View File

@ -19,6 +19,7 @@ parking_lot.workspace = true
async-trait.workspace = true
tokio = { workspace = true, features = ["sync"]}
lib-infra = { workspace = true }
futures = "0.3"
[features]
default = []

View File

@ -3,7 +3,7 @@ use std::sync::{Arc, Weak};
use crate::CollabKVDB;
use anyhow::Error;
use collab::core::collab::{CollabDocState, MutexCollab};
use collab::core::collab::{DocStateSource, MutexCollab};
use collab::preclude::CollabBuilder;
use collab_entity::{CollabObject, CollabType};
use collab_plugins::connect_state::{CollabConnectReachability, CollabConnectState};
@ -68,7 +68,7 @@ impl Display for CollabPluginProviderContext {
pub struct AppFlowyCollabBuilder {
network_reachability: CollabConnectReachability,
workspace_id: RwLock<Option<String>>,
plugin_provider: tokio::sync::RwLock<Arc<dyn CollabCloudPluginProvider>>,
plugin_provider: RwLock<Arc<dyn CollabCloudPluginProvider>>,
snapshot_persistence: Mutex<Option<Arc<dyn SnapshotPersistence>>>,
#[cfg(not(target_arch = "wasm32"))]
rocksdb_backup: Mutex<Option<Arc<dyn RocksdbBackup>>>,
@ -97,7 +97,7 @@ impl AppFlowyCollabBuilder {
Self {
network_reachability: CollabConnectReachability::new(),
workspace_id: Default::default(),
plugin_provider: tokio::sync::RwLock::new(Arc::new(storage_provider)),
plugin_provider: RwLock::new(Arc::new(storage_provider)),
snapshot_persistence: Default::default(),
#[cfg(not(target_arch = "wasm32"))]
rocksdb_backup: Default::default(),
@ -167,22 +167,20 @@ impl AppFlowyCollabBuilder {
uid: i64,
object_id: &str,
object_type: CollabType,
collab_doc_state: CollabDocState,
collab_doc_state: DocStateSource,
collab_db: Weak<CollabKVDB>,
build_config: CollabBuilderConfig,
) -> Result<Arc<MutexCollab>, Error> {
let persistence_config = CollabPersistenceConfig::default();
self
.build_with_config(
uid,
object_id,
object_type,
collab_db,
collab_doc_state,
persistence_config,
build_config,
)
.await
self.build_with_config(
uid,
object_id,
object_type,
collab_db,
collab_doc_state,
persistence_config,
build_config,
)
}
/// Creates a new collaboration builder with the custom configuration.
@ -200,13 +198,13 @@ impl AppFlowyCollabBuilder {
/// - `collab_db`: A weak reference to the [CollabKVDB].
///
#[allow(clippy::too_many_arguments)]
pub async fn build_with_config(
pub fn build_with_config(
&self,
uid: i64,
object_id: &str,
object_type: CollabType,
collab_db: Weak<CollabKVDB>,
collab_doc_state: CollabDocState,
collab_doc_state: DocStateSource,
#[allow(unused_variables)] persistence_config: CollabPersistenceConfig,
build_config: CollabBuilderConfig,
) -> Result<Arc<MutexCollab>, Error> {
@ -240,23 +238,22 @@ impl AppFlowyCollabBuilder {
{
let collab_object = self.collab_object(uid, object_id, object_type)?;
if build_config.sync_enable {
let provider_type = self.plugin_provider.read().await.provider_type();
let provider_type = self.plugin_provider.read().provider_type();
let span = tracing::span!(tracing::Level::TRACE, "collab_builder", object_id = %object_id);
let _enter = span.enter();
match provider_type {
CollabPluginProviderType::AppFlowyCloud => {
trace!("init appflowy cloud collab plugins");
let local_collab = Arc::downgrade(&collab);
let plugins = self
.plugin_provider
.read()
.await
.get_plugins(CollabPluginProviderContext::AppFlowyCloud {
uid,
collab_object,
local_collab,
})
.await;
let plugins =
self
.plugin_provider
.read()
.get_plugins(CollabPluginProviderContext::AppFlowyCloud {
uid,
collab_object,
local_collab,
});
trace!("add appflowy cloud collab plugins: {}", plugins.len());
for plugin in plugins {
@ -269,17 +266,16 @@ impl AppFlowyCollabBuilder {
trace!("init supabase collab plugins");
let local_collab = Arc::downgrade(&collab);
let local_collab_db = collab_db.clone();
let plugins = self
.plugin_provider
.read()
.await
.get_plugins(CollabPluginProviderContext::Supabase {
uid,
collab_object,
local_collab,
local_collab_db,
})
.await;
let plugins =
self
.plugin_provider
.read()
.get_plugins(CollabPluginProviderContext::Supabase {
uid,
collab_object,
local_collab,
local_collab_db,
});
for plugin in plugins {
collab.lock().add_plugin(plugin);
}
@ -291,7 +287,7 @@ impl AppFlowyCollabBuilder {
}
#[cfg(target_arch = "wasm32")]
collab.lock().initialize().await;
futures::executor::block_on(collab.lock().initialize());
#[cfg(not(target_arch = "wasm32"))]
collab.lock().initialize();

View File

@ -1,12 +1,11 @@
use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderType};
use collab::preclude::CollabPlugin;
use lib_infra::future::Fut;
use std::sync::Arc;
pub trait CollabCloudPluginProvider: Send + Sync + 'static {
fn provider_type(&self) -> CollabPluginProviderType;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>>;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>>;
fn is_sync_enabled(&self) -> bool;
}
@ -19,7 +18,7 @@ where
(**self).provider_type()
}
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> {
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
(**self).get_plugins(context)
}

View File

@ -2,12 +2,11 @@ use crate::collab_builder::{CollabPluginProviderContext, CollabPluginProviderTyp
use collab::preclude::CollabPlugin;
use lib_infra::future::Fut;
use std::rc::Rc;
use std::sync::Arc;
pub trait CollabCloudPluginProvider: 'static {
fn provider_type(&self) -> CollabPluginProviderType;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>>;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>>;
fn is_sync_enabled(&self) -> bool;
}
@ -20,7 +19,7 @@ where
(**self).provider_type()
}
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> {
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
(**self).get_plugins(context)
}

View File

@ -1,4 +1,4 @@
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin;
use collab_document::blocks::DocumentData;
use collab_document::document::Document;
@ -108,31 +108,34 @@ impl EventIntegrationTest {
pub async fn get_collab_doc_state(
&self,
oid: &str,
collay_type: CollabType,
) -> Result<CollabDocState, FlowyError> {
collab_type: CollabType,
) -> Result<Vec<u8>, FlowyError> {
let server = self.server_provider.get_server().unwrap();
let workspace_id = self.get_current_workspace().await.id;
let uid = self.get_user_profile().await?.id;
let doc_state = server
.folder_service()
.get_folder_doc_state(&workspace_id, uid, collay_type, oid)
.get_folder_doc_state(&workspace_id, uid, collab_type, oid)
.await?;
Ok(doc_state)
}
}
pub fn document_data_from_document_doc_state(
doc_id: &str,
doc_state: CollabDocState,
) -> DocumentData {
pub fn document_data_from_document_doc_state(doc_id: &str, doc_state: Vec<u8>) -> DocumentData {
document_from_document_doc_state(doc_id, doc_state)
.get_document_data()
.unwrap()
}
pub fn document_from_document_doc_state(doc_id: &str, doc_state: CollabDocState) -> Document {
Document::from_doc_state(CollabOrigin::Empty, doc_state, doc_id, vec![]).unwrap()
pub fn document_from_document_doc_state(doc_id: &str, doc_state: Vec<u8>) -> Document {
Document::from_doc_state(
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
doc_id,
vec![],
)
.unwrap()
}
async fn init_core(config: AppFlowyCoreConfig) -> AppFlowyCore {

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use anyhow::Error;
use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
use collab::core::collab::CollabDocState;
use collab::core::origin::{CollabClient, CollabOrigin};
use collab::preclude::CollabPlugin;
use collab_entity::CollabType;
@ -26,7 +26,7 @@ use flowy_server_pub::supabase_config::SupabaseConfiguration;
use flowy_storage::ObjectValue;
use flowy_user_pub::cloud::{UserCloudService, UserCloudServiceProvider};
use flowy_user_pub::entities::{Authenticator, UserTokenState};
use lib_infra::future::{to_fut, Fut, FutureResult};
use lib_infra::future::FutureResult;
use crate::integrate::server::{Server, ServerProvider};
@ -184,7 +184,7 @@ impl FolderCloudService for ServerProvider {
uid: i64,
collab_type: CollabType,
object_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
let object_id = object_id.to_string();
let workspace_id = workspace_id.to_string();
let server = self.get_server();
@ -225,7 +225,7 @@ impl DatabaseCloudService for ServerProvider {
object_id: &str,
collab_type: CollabType,
workspace_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
let workspace_id = workspace_id.to_string();
let server = self.get_server();
let database_id = object_id.to_string();
@ -274,7 +274,7 @@ impl DocumentCloudService for ServerProvider {
&self,
document_id: &str,
workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> {
) -> FutureResult<Vec<u8>, FlowyError> {
let workspace_id = workspace_id.to_string();
let document_id = document_id.to_string();
let server = self.get_server();
@ -326,61 +326,58 @@ impl CollabCloudPluginProvider for ServerProvider {
}
#[instrument(level = "debug", skip(self, context), fields(server_type = %self.get_server_type()))]
fn get_plugins(&self, context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> {
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
// If the user is local, we don't need to create a sync plugin.
if self.get_server_type().is_local() {
debug!(
"User authenticator is local, skip create sync plugin for: {}",
context
);
return to_fut(async move { vec![] });
return vec![];
}
match context {
CollabPluginProviderContext::Local => to_fut(async move { vec![] }),
CollabPluginProviderContext::Local => vec![],
CollabPluginProviderContext::AppFlowyCloud {
uid: _,
collab_object,
local_collab,
} => {
if let Ok(server) = self.get_server() {
to_fut(async move {
let mut plugins: Vec<Box<dyn CollabPlugin>> = vec![];
// to_fut(async move {
let mut plugins: Vec<Box<dyn CollabPlugin>> = vec![];
// If the user is local, we don't need to create a sync plugin.
// If the user is local, we don't need to create a sync plugin.
match server.collab_ws_channel(&collab_object.object_id).await {
Ok(Some((channel, ws_connect_state, is_connected))) => {
let origin = CollabOrigin::Client(CollabClient::new(
collab_object.uid,
collab_object.device_id.clone(),
));
let sync_object = SyncObject::from(collab_object);
let (sink, stream) = (channel.sink(), channel.stream());
let sink_config = SinkConfig::new().send_timeout(8);
let sync_plugin = SyncPlugin::new(
origin,
sync_object,
local_collab,
sink,
sink_config,
stream,
Some(channel),
!is_connected,
ws_connect_state,
);
plugins.push(Box::new(sync_plugin));
},
Ok(None) => {
tracing::error!("🔴Failed to get collab ws channel: channel is none");
},
Err(err) => tracing::error!("🔴Failed to get collab ws channel: {:?}", err),
}
plugins
})
match server.collab_ws_channel(&collab_object.object_id) {
Ok(Some((channel, ws_connect_state, is_connected))) => {
let origin = CollabOrigin::Client(CollabClient::new(
collab_object.uid,
collab_object.device_id.clone(),
));
let sync_object = SyncObject::from(collab_object);
let (sink, stream) = (channel.sink(), channel.stream());
let sink_config = SinkConfig::new().send_timeout(8);
let sync_plugin = SyncPlugin::new(
origin,
sync_object,
local_collab,
sink,
sink_config,
stream,
Some(channel),
!is_connected,
ws_connect_state,
);
plugins.push(Box::new(sync_plugin));
},
Ok(None) => {
tracing::error!("🔴Failed to get collab ws channel: channel is none");
},
Err(err) => tracing::error!("🔴Failed to get collab ws channel: {:?}", err),
}
plugins
} else {
to_fut(async move { vec![] })
vec![]
}
},
CollabPluginProviderContext::Supabase {
@ -404,8 +401,7 @@ impl CollabCloudPluginProvider for ServerProvider {
local_collab_db,
)));
}
to_fut(async move { plugins })
plugins
},
}
}

View File

@ -1,12 +1,10 @@
use anyhow::Error;
use collab::core::collab::DocStateSource;
use collab_entity::CollabType;
use lib_infra::future::FutureResult;
use std::collections::HashMap;
use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType;
use lib_infra::future::FutureResult;
pub type CollabDocStateByOid = HashMap<String, CollabDocState>;
pub type CollabDocStateByOid = HashMap<String, DocStateSource>;
/// A trait for database cloud service.
/// Each kind of server should implement this trait. Check out the [AppFlowyServerProvider] of
@ -17,7 +15,7 @@ pub trait DatabaseCloudService: Send + Sync {
object_id: &str,
collab_type: CollabType,
workspace_id: &str,
) -> FutureResult<CollabDocState, Error>;
) -> FutureResult<Vec<u8>, Error>;
fn batch_get_database_object_doc_state(
&self,

View File

@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::num::NonZeroUsize;
use std::sync::{Arc, Weak};
use collab::core::collab::{CollabDocState, MutexCollab};
use collab::core::collab::{DocStateSource, MutexCollab};
use collab_database::blocks::BlockEvent;
use collab_database::database::{get_inline_view_id, DatabaseData, MutexDatabase};
use collab_database::error::DatabaseError;
@ -12,7 +12,7 @@ use collab_database::user::{
use collab_database::views::{CreateDatabaseParams, CreateViewParams, DatabaseLayout};
use collab_entity::CollabType;
use collab_plugins::local_storage::kv::KVTransactionDB;
use futures::executor::block_on;
use lru::LruCache;
use tokio::sync::{Mutex, RwLock};
use tracing::{event, instrument, trace};
@ -98,7 +98,7 @@ impl DatabaseManager {
};
let config = CollabPersistenceConfig::new().snapshot_per_update(100);
let mut workspace_database_doc_state = CollabDocState::default();
let mut workspace_database_doc_state = DocStateSource::FromDisk;
// If the workspace database not exist in disk, try to fetch from remote.
if !self.is_collab_exist(uid, &collab_db, &workspace_database_object_id) {
trace!("workspace database not exist, try to fetch from remote");
@ -111,8 +111,8 @@ impl DatabaseManager {
)
.await
{
Ok(remote_doc_state) => {
workspace_database_doc_state = remote_doc_state;
Ok(doc_state) => {
workspace_database_doc_state = DocStateSource::FromDocState(doc_state);
},
Err(err) => {
return Err(FlowyError::record_not_found().with_context(format!(
@ -423,7 +423,7 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
&self,
object_id: &str,
object_ty: CollabType,
) -> CollabFuture<Result<CollabDocState, DatabaseError>> {
) -> CollabFuture<Result<DocStateSource, DatabaseError>> {
let workspace_id = self.workspace_id.clone();
let object_id = object_id.to_string();
let weak_cloud_service = Arc::downgrade(&self.cloud_service);
@ -431,13 +431,13 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
match weak_cloud_service.upgrade() {
None => {
tracing::warn!("Cloud service is dropped");
Ok(vec![])
Ok(DocStateSource::FromDocState(vec![]))
},
Some(cloud_service) => {
let updates = cloud_service
let doc_state = cloud_service
.get_database_object_doc_state(&object_id, object_ty, &workspace_id)
.await?;
Ok(updates)
Ok(DocStateSource::FromDocState(doc_state))
},
}
})
@ -472,18 +472,20 @@ impl DatabaseCollabService for UserDatabaseCollabServiceImpl {
object_id: &str,
object_type: CollabType,
collab_db: Weak<CollabKVDB>,
collab_raw_data: CollabDocState,
collab_raw_data: DocStateSource,
persistence_config: CollabPersistenceConfig,
) -> Arc<MutexCollab> {
block_on(self.collab_builder.build_with_config(
uid,
object_id,
object_type,
collab_db,
collab_raw_data,
persistence_config,
CollabBuilderConfig::default().sync_enable(true),
))
.unwrap()
self
.collab_builder
.build_with_config(
uid,
object_id,
object_type,
collab_db,
collab_raw_data,
persistence_config,
CollabBuilderConfig::default().sync_enable(true),
)
.unwrap()
}
}

View File

@ -805,6 +805,7 @@ impl DatabaseEditor {
}?;
(field, database.get_cell(field_id, &row_id).cell)
};
let new_cell =
apply_cell_changeset(cell_changeset, cell, &field, Some(self.cell_cache.clone()))?;
self.update_cell(view_id, row_id, field_id, new_cell).await

View File

@ -1,5 +1,4 @@
use anyhow::Error;
use collab::core::collab::CollabDocState;
pub use collab_document::blocks::DocumentData;
use flowy_error::FlowyError;
@ -13,7 +12,7 @@ pub trait DocumentCloudService: Send + Sync + 'static {
&self,
document_id: &str,
workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError>;
) -> FutureResult<Vec<u8>, FlowyError>;
fn get_document_snapshots(
&self,

View File

@ -2,7 +2,7 @@ use std::num::NonZeroUsize;
use std::sync::Arc;
use std::sync::Weak;
use collab::core::collab::{CollabDocState, MutexCollab};
use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::collab_plugin::EncodedCollab;
use collab::core::origin::CollabOrigin;
use collab::preclude::Collab;
@ -16,8 +16,6 @@ use lru::LruCache;
use parking_lot::Mutex;
use tokio::io::AsyncWriteExt;
use tracing::error;
use tracing::info;
use tracing::warn;
use tracing::{event, instrument};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
@ -122,7 +120,7 @@ impl DocumentManager {
.doc_state
.to_vec();
let collab = self
.collab_for_document(uid, doc_id, doc_state, false)
.collab_for_document(uid, doc_id, DocStateSource::FromDocState(doc_state), false)
.await?;
collab.lock().flush();
Ok(())
@ -138,14 +136,16 @@ impl DocumentManager {
return Ok(doc);
}
let mut doc_state = CollabDocState::default();
let mut doc_state = DocStateSource::FromDisk;
// If the document does not exist in local disk, try get the doc state from the cloud. This happens
// When user_device_a create a document and user_device_b open the document.
if !self.is_doc_exist(doc_id).await? {
doc_state = self
.cloud_service
.get_document_doc_state(doc_id, &self.user_service.workspace_id()?)
.await?;
doc_state = DocStateSource::FromDocState(
self
.cloud_service
.get_document_doc_state(doc_id, &self.user_service.workspace_id()?)
.await?,
);
// the doc_state should not be empty if remote return the doc state without error.
if doc_state.is_empty() {
@ -183,16 +183,16 @@ impl DocumentManager {
}
pub async fn get_document_data(&self, doc_id: &str) -> FlowyResult<DocumentData> {
let mut updates = vec![];
let mut doc_state = vec![];
if !self.is_doc_exist(doc_id).await? {
updates = self
doc_state = self
.cloud_service
.get_document_doc_state(doc_id, &self.user_service.workspace_id()?)
.await?;
}
let uid = self.user_service.user_id()?;
let collab = self
.collab_for_document(uid, doc_id, updates, false)
.collab_for_document(uid, doc_id, DocStateSource::FromDocState(doc_state), false)
.await?;
Document::open(collab)?
.get_document_data()
@ -284,7 +284,7 @@ impl DocumentManager {
#[cfg(not(target_arch = "wasm32"))]
{
if tokio::fs::metadata(&local_file_path).await.is_ok() {
warn!("file already exist in user local disk: {}", local_file_path);
tracing::warn!("file already exist in user local disk: {}", local_file_path);
return Ok(());
}
@ -298,7 +298,7 @@ impl DocumentManager {
.await?;
let n = file.write(&object_value.raw).await?;
info!("downloaded {} bytes to file: {}", n, local_file_path);
tracing::info!("downloaded {} bytes to file: {}", n, local_file_path);
}
Ok(())
}
@ -326,22 +326,19 @@ impl DocumentManager {
&self,
uid: i64,
doc_id: &str,
doc_state: CollabDocState,
doc_state: DocStateSource,
sync_enable: bool,
) -> FlowyResult<Arc<MutexCollab>> {
let db = self.user_service.collab_db(uid)?;
let collab = self
.collab_builder
.build_with_config(
uid,
doc_id,
CollabType::Document,
db,
doc_state,
CollabPersistenceConfig::default().snapshot_per_update(1000),
CollabBuilderConfig::default().sync_enable(sync_enable),
)
.await?;
let collab = self.collab_builder.build_with_config(
uid,
doc_id,
CollabType::Document,
db,
doc_state,
CollabPersistenceConfig::default().snapshot_per_update(1000),
CollabBuilderConfig::default().sync_enable(sync_enable),
)?;
Ok(collab)
}

View File

@ -2,7 +2,6 @@ use std::ops::Deref;
use std::sync::Arc;
use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab::preclude::CollabPlugin;
use collab_document::blocks::DocumentData;
use collab_document::document_data::default_document_data;
@ -24,7 +23,7 @@ use flowy_document_pub::cloud::*;
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_storage::ObjectStorageService;
use lib_infra::async_trait::async_trait;
use lib_infra::future::{to_fut, Fut, FutureResult};
use lib_infra::future::FutureResult;
pub struct DocumentTest {
inner: DocumentManager,
@ -135,7 +134,7 @@ impl DocumentCloudService for LocalTestDocumentCloudServiceImpl {
&self,
document_id: &str,
_workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> {
) -> FutureResult<Vec<u8>, FlowyError> {
let document_id = document_id.to_string();
FutureResult::new(async move {
Err(FlowyError::new(
@ -197,8 +196,8 @@ impl CollabCloudPluginProvider for DefaultCollabStorageProvider {
CollabPluginProviderType::Local
}
fn get_plugins(&self, _context: CollabPluginProviderContext) -> Fut<Vec<Box<dyn CollabPlugin>>> {
to_fut(async move { vec![] })
fn get_plugins(&self, _context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
vec![]
}
fn is_sync_enabled(&self) -> bool {

View File

@ -1,5 +1,4 @@
pub use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType;
pub use collab_folder::{Folder, FolderData, Workspace};
use uuid::Uuid;
@ -36,7 +35,7 @@ pub trait FolderCloudService: Send + Sync + 'static {
uid: i64,
collab_type: CollabType,
object_id: &str,
) -> FutureResult<CollabDocState, Error>;
) -> FutureResult<Vec<u8>, Error>;
fn batch_create_folder_collab_objects(
&self,

View File

@ -1,25 +1,3 @@
use std::fmt::{Display, Formatter};
use std::ops::Deref;
use std::sync::{Arc, Weak};
use collab::core::collab::{CollabDocState, MutexCollab};
use collab_entity::CollabType;
use collab_folder::error::FolderError;
use collab_folder::{
Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout,
ViewUpdate, Workspace,
};
use parking_lot::{Mutex, RwLock};
use tracing::{error, info, instrument};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
use collab_integrate::{CollabKVDB, CollabPersistenceConfig};
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
use flowy_folder_pub::folder_builder::ParentChildViews;
use lib_infra::conditional_send_sync_trait;
use crate::entities::icon::UpdateViewIconParams;
use crate::entities::{
view_pb_with_child_views, view_pb_without_child_views, CreateViewParams, CreateWorkspaceParams,
@ -38,6 +16,24 @@ use crate::util::{
folder_not_init_error, insert_parent_child_views, workspace_data_not_sync_error,
};
use crate::view_operation::{create_view, FolderOperationHandler, FolderOperationHandlers};
use collab::core::collab::{DocStateSource, MutexCollab};
use collab_entity::CollabType;
use collab_folder::error::FolderError;
use collab_folder::{
Folder, FolderData, FolderNotify, Section, SectionItem, TrashInfo, UserId, View, ViewLayout,
ViewUpdate, Workspace,
};
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabBuilderConfig};
use collab_integrate::{CollabKVDB, CollabPersistenceConfig};
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
use flowy_folder_pub::folder_builder::ParentChildViews;
use lib_infra::conditional_send_sync_trait;
use parking_lot::{Mutex, RwLock};
use std::fmt::{Display, Formatter};
use std::ops::Deref;
use std::sync::{Arc, Weak};
use tracing::{error, info, instrument};
conditional_send_sync_trait! {
"[crate::manager::FolderUser] represents the user for folder.";
@ -164,24 +160,21 @@ impl FolderManager {
uid: i64,
workspace_id: &str,
collab_db: Weak<CollabKVDB>,
collab_doc_state: CollabDocState,
doc_state: DocStateSource,
folder_notifier: T,
) -> Result<Folder, FlowyError> {
let folder_notifier = folder_notifier.into();
let collab = self
.collab_builder
.build_with_config(
uid,
workspace_id,
CollabType::Folder,
collab_db,
collab_doc_state,
CollabPersistenceConfig::new()
.enable_snapshot(true)
.snapshot_per_update(50),
CollabBuilderConfig::default().sync_enable(true),
)
.await?;
let collab = self.collab_builder.build_with_config(
uid,
workspace_id,
CollabType::Folder,
collab_db,
doc_state,
CollabPersistenceConfig::new()
.enable_snapshot(true)
.snapshot_per_update(50),
CollabBuilderConfig::default().sync_enable(true),
)?;
let (should_clear, err) = match Folder::open(UserId::from(uid), collab, folder_notifier) {
Ok(folder) => {
return Ok(folder);
@ -207,20 +200,17 @@ impl FolderManager {
workspace_id: &str,
collab_db: Weak<CollabKVDB>,
) -> Result<Arc<MutexCollab>, FlowyError> {
let collab = self
.collab_builder
.build_with_config(
uid,
workspace_id,
CollabType::Folder,
collab_db,
vec![],
CollabPersistenceConfig::new()
.enable_snapshot(true)
.snapshot_per_update(50),
CollabBuilderConfig::default().sync_enable(true),
)
.await?;
let collab = self.collab_builder.build_with_config(
uid,
workspace_id,
CollabType::Folder,
collab_db,
DocStateSource::FromDocState(vec![]),
CollabPersistenceConfig::new()
.enable_snapshot(true)
.snapshot_per_update(50),
CollabBuilderConfig::default().sync_enable(true),
)?;
Ok(collab)
}
@ -1229,7 +1219,7 @@ pub enum FolderInitDataSource {
/// It means using the data stored on local disk to initialize the folder
LocalDisk { create_if_not_exist: bool },
/// If there is no data stored on local disk, we will use the data from the server to initialize the folder
Cloud(CollabDocState),
Cloud(Vec<u8>),
/// If the user is new, we use the [DefaultFolderBuilder] to create the default folder.
FolderData(FolderData),
}

View File

@ -6,6 +6,7 @@ use collab_integrate::CollabKVDB;
use flowy_error::{FlowyError, FlowyResult};
use collab::core::collab::DocStateSource;
use std::sync::{Arc, Weak};
use tracing::{event, Level};
@ -54,7 +55,13 @@ impl FolderManager {
if is_exist {
event!(Level::INFO, "Init folder from local disk");
self
.make_folder(uid, &workspace_id, collab_db, vec![], folder_notifier)
.make_folder(
uid,
&workspace_id,
collab_db,
DocStateSource::FromDisk,
folder_notifier,
)
.await?
} else if create_if_not_exist {
// 2. if the folder doesn't exist and create_if_not_exist is true, create a default folder
@ -76,7 +83,7 @@ impl FolderManager {
uid,
&workspace_id,
collab_db.clone(),
doc_state,
DocStateSource::FromDocState(doc_state),
folder_notifier.clone(),
)
.await?
@ -86,7 +93,13 @@ impl FolderManager {
if doc_state.is_empty() {
event!(Level::ERROR, "remote folder data is empty, open from local");
self
.make_folder(uid, &workspace_id, collab_db, vec![], folder_notifier)
.make_folder(
uid,
&workspace_id,
collab_db,
DocStateSource::FromDisk,
folder_notifier,
)
.await?
} else {
event!(Level::INFO, "Restore folder from remote data");
@ -95,7 +108,7 @@ impl FolderManager {
uid,
&workspace_id,
collab_db.clone(),
doc_state,
DocStateSource::FromDocState(doc_state),
folder_notifier.clone(),
)
.await?

View File

@ -2,7 +2,7 @@ use anyhow::Error;
use client_api::entity::QueryCollabResult::{Failed, Success};
use client_api::entity::{QueryCollab, QueryCollabParams};
use client_api::error::ErrorCode::RecordNotFound;
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab::core::collab_plugin::EncodedCollab;
use collab_entity::CollabType;
use tracing::error;
@ -23,7 +23,7 @@ where
object_id: &str,
collab_type: CollabType,
workspace_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
let workspace_id = workspace_id.to_string();
let object_id = object_id.to_string();
let try_get_client = self.0.try_get_client();
@ -73,7 +73,10 @@ where
.flat_map(|(object_id, result)| match result {
Success { encode_collab_v1 } => {
match EncodedCollab::decode_from_bytes(&encode_collab_v1) {
Ok(encode) => Some((object_id, encode.doc_state.to_vec())),
Ok(encode) => Some((
object_id,
DocStateSource::FromDocState(encode.doc_state.to_vec()),
)),
Err(err) => {
error!("Failed to decode collab: {}", err);
None

View File

@ -1,6 +1,6 @@
use anyhow::Error;
use client_api::entity::{QueryCollab, QueryCollabParams};
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin;
use collab_document::document::Document;
use collab_entity::CollabType;
@ -21,7 +21,7 @@ where
&self,
document_id: &str,
workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> {
) -> FutureResult<Vec<u8>, FlowyError> {
let workspace_id = workspace_id.to_string();
let try_get_client = self.0.try_get_client();
let document_id = document_id.to_string();
@ -74,8 +74,12 @@ where
.map_err(FlowyError::from)?
.doc_state
.to_vec();
let document =
Document::from_doc_state(CollabOrigin::Empty, doc_state, &document_id, vec![])?;
let document = Document::from_doc_state(
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&document_id,
vec![],
)?;
Ok(document.get_document_data().ok())
})
}

View File

@ -2,7 +2,7 @@ use anyhow::Error;
use client_api::entity::{
workspace_dto::CreateWorkspaceParam, CollabParams, QueryCollab, QueryCollabParams,
};
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin;
use collab_entity::CollabType;
use collab_folder::RepeatedViewIdentifier;
@ -96,8 +96,13 @@ where
.map_err(FlowyError::from)?
.doc_state
.to_vec();
let folder =
Folder::from_collab_doc_state(uid, CollabOrigin::Empty, doc_state, &workspace_id, vec![])?;
let folder = Folder::from_collab_doc_state(
uid,
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&workspace_id,
vec![],
)?;
Ok(folder.get_folder_data())
})
}
@ -116,7 +121,7 @@ where
_uid: i64,
collab_type: CollabType,
object_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
let object_id = object_id.to_string();
let workspace_id = workspace_id.to_string();
let try_get_client = self.0.try_get_client();

View File

@ -7,7 +7,6 @@ use client_api::entity::workspace_dto::{
};
use client_api::entity::{AFRole, AFWorkspace, AuthProvider, CollabParams, CreateCollabParams};
use client_api::{Client, ClientConfiguration};
use collab::core::collab::CollabDocState;
use collab_entity::CollabObject;
use parking_lot::RwLock;
@ -239,7 +238,7 @@ where
})
}
fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<CollabDocState, FlowyError> {
fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<Vec<u8>, FlowyError> {
FutureResult::new(async { Ok(vec![]) })
}

View File

@ -25,7 +25,6 @@ use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
use flowy_user_pub::cloud::{UserCloudService, UserUpdate};
use flowy_user_pub::entities::UserTokenState;
use lib_dispatch::prelude::af_spawn;
use lib_infra::future::FutureResult;
use crate::af_cloud::impls::{
AFCloudDatabaseCloudServiceImpl, AFCloudDocumentCloudServiceImpl, AFCloudFileStorageServiceImpl,
@ -196,7 +195,7 @@ impl AppFlowyServer for AppFlowyCloudServer {
fn collab_ws_channel(
&self,
_object_id: &str,
) -> FutureResult<
) -> Result<
Option<(
Arc<WebSocketChannel<ServerCollabMessage>>,
WSConnectStateReceiver,
@ -204,22 +203,10 @@ impl AppFlowyServer for AppFlowyCloudServer {
)>,
Error,
> {
if self.enable_sync.load(Ordering::SeqCst) {
let object_id = _object_id.to_string();
let weak_ws_client = Arc::downgrade(&self.ws_client);
FutureResult::new(async move {
match weak_ws_client.upgrade() {
None => Ok(None),
Some(ws_client) => {
let channel = ws_client.subscribe_collab(object_id).ok();
let connect_state_recv = ws_client.subscribe_connect_state();
Ok(channel.map(|c| (c, connect_state_recv, ws_client.is_connected())))
},
}
})
} else {
FutureResult::new(async { Ok(None) })
}
let object_id = _object_id.to_string();
let channel = self.ws_client.subscribe_collab(object_id).ok();
let connect_state_recv = self.ws_client.subscribe_connect_state();
Ok(channel.map(|c| (c, connect_state_recv, self.ws_client.is_connected())))
}
fn file_storage(&self) -> Option<Arc<dyn ObjectStorageService>> {

View File

@ -1,5 +1,4 @@
use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType;
use flowy_database_pub::cloud::{CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot};
@ -13,7 +12,7 @@ impl DatabaseCloudService for LocalServerDatabaseCloudServiceImpl {
_object_id: &str,
_collab_type: CollabType,
_workspace_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
FutureResult::new(async move { Ok(vec![]) })
}

View File

@ -1,5 +1,4 @@
use anyhow::Error;
use collab::core::collab::CollabDocState;
use flowy_document_pub::cloud::*;
use flowy_error::{ErrorCode, FlowyError};
@ -12,7 +11,7 @@ impl DocumentCloudService for LocalServerDocumentCloudServiceImpl {
&self,
document_id: &str,
_workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> {
) -> FutureResult<Vec<u8>, FlowyError> {
let document_id = document_id.to_string();
FutureResult::new(async move {
Err(FlowyError::new(

View File

@ -1,7 +1,6 @@
use std::sync::Arc;
use anyhow::{anyhow, Error};
use collab::core::collab::CollabDocState;
use collab_entity::CollabType;
use flowy_folder_pub::cloud::{
@ -59,7 +58,7 @@ impl FolderCloudService for LocalServerFolderCloudServiceImpl {
_uid: i64,
_collab_type: CollabType,
_object_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
FutureResult::new(async {
Err(anyhow!(
"Local server doesn't support get collab doc state from remote"

View File

@ -1,6 +1,5 @@
use std::sync::Arc;
use collab::core::collab::CollabDocState;
use collab_entity::CollabObject;
use lazy_static::lazy_static;
use parking_lot::Mutex;
@ -149,7 +148,7 @@ impl UserCloudService for LocalServerUserAuthServiceImpl {
FutureResult::new(async { Ok(vec![]) })
}
fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<CollabDocState, FlowyError> {
fn get_user_awareness_doc_state(&self, _uid: i64) -> FutureResult<Vec<u8>, FlowyError> {
FutureResult::new(async { Ok(vec![]) })
}

View File

@ -16,7 +16,6 @@ use flowy_document_pub::cloud::DocumentCloudService;
use flowy_folder_pub::cloud::FolderCloudService;
use flowy_user_pub::cloud::UserCloudService;
use flowy_user_pub::entities::UserTokenState;
use lib_infra::future::FutureResult;
pub trait AppFlowyEncryption: Send + Sync + 'static {
fn get_secret(&self) -> Option<String>;
@ -123,7 +122,7 @@ pub trait AppFlowyServer: Send + Sync + 'static {
fn collab_ws_channel(
&self,
_object_id: &str,
) -> FutureResult<
) -> Result<
Option<(
Arc<WebSocketChannel<ServerCollabMessage>>,
WSConnectStateReceiver,
@ -131,7 +130,7 @@ pub trait AppFlowyServer: Send + Sync + 'static {
)>,
anyhow::Error,
> {
FutureResult::new(async { Ok(None) })
Ok(None)
}
fn file_storage(&self) -> Option<Arc<dyn ObjectStorageService>>;

View File

@ -4,7 +4,7 @@ use std::sync::{Arc, Weak};
use anyhow::Error;
use chrono::{DateTime, Utc};
use client_api::collab_sync::collab_msg::MsgId;
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab::preclude::merge_updates_v1;
use collab_entity::CollabObject;
use collab_plugins::cloud_storage::{
@ -62,7 +62,7 @@ where
true
}
async fn get_doc_state(&self, object: &CollabObject) -> Result<CollabDocState, Error> {
async fn get_doc_state(&self, object: &CollabObject) -> Result<DocStateSource, Error> {
let postgrest = self.server.try_get_weak_postgrest()?;
let action = FetchObjectUpdateAction::new(
object.object_id.clone(),
@ -70,7 +70,7 @@ where
postgrest,
);
let doc_state = action.run().await?;
Ok(doc_state)
Ok(DocStateSource::FromDocState(doc_state))
}
async fn get_snapshots(&self, object_id: &str, limit: usize) -> Vec<RemoteCollabSnapshot> {

View File

@ -1,5 +1,4 @@
use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab_entity::CollabType;
use tokio::sync::oneshot::channel;
@ -31,7 +30,7 @@ where
object_id: &str,
collab_type: CollabType,
_workspace_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
let try_get_postgrest = self.server.try_get_weak_postgrest();
let object_id = object_id.to_string();
let (tx, rx) = channel();

View File

@ -1,5 +1,5 @@
use anyhow::Error;
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin;
use collab_document::blocks::DocumentData;
use collab_document::document::Document;
@ -33,7 +33,7 @@ where
&self,
document_id: &str,
workspace_id: &str,
) -> FutureResult<CollabDocState, FlowyError> {
) -> FutureResult<Vec<u8>, FlowyError> {
let try_get_postgrest = self.server.try_get_weak_postgrest();
let document_id = document_id.to_string();
let (tx, rx) = channel();
@ -94,8 +94,12 @@ where
let action =
FetchObjectUpdateAction::new(document_id.clone(), CollabType::Document, postgrest);
let doc_state = action.run_with_fix_interval(5, 10).await?;
let document =
Document::from_doc_state(CollabOrigin::Empty, doc_state, &document_id, vec![])?;
let document = Document::from_doc_state(
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&document_id,
vec![],
)?;
Ok(document.get_document_data().ok())
}
.await,

View File

@ -2,7 +2,7 @@ use std::str::FromStr;
use anyhow::{anyhow, Error};
use chrono::{DateTime, Utc};
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab::core::origin::CollabOrigin;
use collab_entity::CollabType;
use serde_json::Value;
@ -102,8 +102,13 @@ where
let doc_state = merge_updates_v1(&updates)
.map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?;
let folder =
Folder::from_collab_doc_state(uid, CollabOrigin::Empty, doc_state, &workspace_id, vec![])?;
let folder = Folder::from_collab_doc_state(
uid,
CollabOrigin::Empty,
DocStateSource::FromDocState(doc_state),
&workspace_id,
vec![],
)?;
Ok(folder.get_folder_data())
})
}
@ -137,7 +142,7 @@ where
_uid: i64,
collab_type: CollabType,
object_id: &str,
) -> FutureResult<CollabDocState, Error> {
) -> FutureResult<Vec<u8>, Error> {
let try_get_postgrest = self.server.try_get_weak_postgrest();
let object_id = object_id.to_string();
let (tx, rx) = channel();

View File

@ -7,7 +7,7 @@ use std::time::Duration;
use anyhow::Error;
use chrono::{DateTime, Utc};
use collab::core::collab::CollabDocState;
use collab::core::collab::DocStateSource;
use collab_entity::{CollabObject, CollabType};
use collab_plugins::cloud_storage::RemoteCollabSnapshot;
use serde_json::Value;
@ -60,7 +60,7 @@ impl FetchObjectUpdateAction {
impl Action for FetchObjectUpdateAction {
type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send>>;
type Item = CollabDocState;
type Item = Vec<u8>;
type Error = anyhow::Error;
fn run(&mut self) -> Self::Future {
@ -284,7 +284,7 @@ pub async fn batch_get_updates_from_server(
match parser_updates_form_json(record.clone(), &postgrest.secret()) {
Ok(items) => {
if items.is_empty() {
updates_by_oid.insert(oid.to_string(), vec![]);
updates_by_oid.insert(oid.to_string(), DocStateSource::FromDocState(vec![]));
} else {
let updates = items
.iter()
@ -293,7 +293,7 @@ pub async fn batch_get_updates_from_server(
let doc_state = merge_updates_v1(&updates)
.map_err(|err| anyhow::anyhow!("merge updates failed: {:?}", err))?;
updates_by_oid.insert(oid.to_string(), doc_state);
updates_by_oid.insert(oid.to_string(), DocStateSource::FromDocState(doc_state));
}
},
Err(e) => {

View File

@ -6,7 +6,7 @@ use std::sync::{Arc, Weak};
use std::time::Duration;
use anyhow::Error;
use collab::core::collab::{CollabDocState, MutexCollab};
use collab::core::collab::MutexCollab;
use collab::core::origin::CollabOrigin;
use collab_entity::{CollabObject, CollabType};
use parking_lot::RwLock;
@ -249,7 +249,7 @@ where
})
}
fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<CollabDocState, FlowyError> {
fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<Vec<u8>, FlowyError> {
let try_get_postgrest = self.server.try_get_weak_postgrest();
let awareness_id = uid.to_string();
let (tx, rx) = channel();

View File

@ -1,3 +1,4 @@
use collab::core::collab::DocStateSource;
use collab_entity::{CollabObject, CollabType};
use uuid::Uuid;
@ -50,7 +51,12 @@ async fn supabase_create_database_test() {
.unwrap();
assert_eq!(updates_by_oid.len(), 3);
for (_, update) in updates_by_oid {
assert_eq!(update.len(), 2);
for (_, source) in updates_by_oid {
match source {
DocStateSource::FromDisk => panic!("should not be from disk"),
DocStateSource::FromDocState(doc_state) => {
assert_eq!(doc_state.len(), 2);
},
}
}
}

View File

@ -2,7 +2,7 @@ use flowy_storage::ObjectStorageService;
use std::collections::HashMap;
use std::sync::Arc;
use collab::core::collab::MutexCollab;
use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::origin::CollabOrigin;
use collab_plugins::cloud_storage::RemoteCollabStorage;
use uuid::Uuid;
@ -122,8 +122,14 @@ pub async fn print_encryption_folder_snapshot(
.pop()
.unwrap();
let collab = Arc::new(
MutexCollab::new_with_doc_state(CollabOrigin::Empty, folder_id, snapshot.blob, vec![], false)
.unwrap(),
MutexCollab::new_with_doc_state(
CollabOrigin::Empty,
folder_id,
DocStateSource::FromDocState(snapshot.blob),
vec![],
false,
)
.unwrap(),
);
let folder_data = Folder::open(uid, collab, None)
.unwrap()

View File

@ -1,4 +1,3 @@
use collab::core::collab::CollabDocState;
use collab_entity::{CollabObject, CollabType};
use flowy_error::{internal_error, ErrorCode, FlowyError};
use lib_infra::box_any::BoxAny;
@ -213,7 +212,7 @@ pub trait UserCloudService: Send + Sync + 'static {
FutureResult::new(async { Ok(vec![]) })
}
fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<CollabDocState, FlowyError>;
fn get_user_awareness_doc_state(&self, uid: i64) -> FutureResult<Vec<u8>, FlowyError>;
fn receive_realtime_event(&self, _json: Value) {}

View File

@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut};
use std::sync::Arc;
use anyhow::anyhow;
use collab::core::collab::MutexCollab;
use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::origin::{CollabClient, CollabOrigin};
use collab::preclude::Collab;
use collab_database::database::{
@ -305,9 +305,14 @@ where
}
let origin = CollabOrigin::Client(CollabClient::new(new_uid, "phantom"));
let new_folder_collab =
Collab::new_with_doc_state(origin, new_workspace_id, vec![], vec![], false)
.map_err(|err| PersistenceError::Internal(err.into()))?;
let new_folder_collab = Collab::new_with_doc_state(
origin,
new_workspace_id,
DocStateSource::FromDisk,
vec![],
false,
)
.map_err(|err| PersistenceError::Internal(err.into()))?;
let mutex_collab = Arc::new(MutexCollab::from_collab(new_folder_collab));
let new_user_id = UserId::from(new_uid);
info!("migrated folder: {:?}", folder_data);

View File

@ -5,7 +5,7 @@ use crate::services::entities::UserPaths;
use crate::services::sqlite_sql::user_sql::select_user_profile;
use crate::user_manager::run_collab_data_migration;
use anyhow::anyhow;
use collab::core::collab::{CollabDocState, MutexCollab};
use collab::core::collab::{DocStateSource, MutexCollab};
use collab::core::origin::CollabOrigin;
use collab::core::transaction::DocTransactionExtension;
use collab::preclude::updates::decoder::Decode;
@ -447,7 +447,7 @@ where
}
fn import_collab_object_with_doc_state<'a, W>(
doc_state: CollabDocState,
doc_state: Vec<u8>,
new_uid: i64,
new_object_id: &str,
w_txn: &'a W,
@ -456,8 +456,13 @@ where
W: CollabKVAction<'a>,
PersistenceError: From<W::Error>,
{
let collab =
Collab::new_with_doc_state(CollabOrigin::Empty, new_object_id, doc_state, vec![], false)?;
let collab = Collab::new_with_doc_state(
CollabOrigin::Empty,
new_object_id,
DocStateSource::FromDocState(doc_state),
vec![],
false,
)?;
write_collab_object(&collab, new_uid, new_object_id, w_txn);
Ok(())
}

View File

@ -1,7 +1,7 @@
use std::sync::{Arc, Weak};
use anyhow::Context;
use collab::core::collab::{CollabDocState, MutexCollab};
use collab::core::collab::{DocStateSource, MutexCollab};
use collab_entity::reminder::Reminder;
use collab_entity::CollabType;
use collab_integrate::collab_builder::CollabBuilderConfig;
@ -164,7 +164,7 @@ impl UserManager {
&self,
session: &Session,
collab_db: Weak<CollabKVDB>,
raw_data: CollabDocState,
doc_state: Vec<u8>,
) -> Result<Arc<MutexCollab>, FlowyError> {
let collab_builder = self.collab_builder.upgrade().ok_or(FlowyError::new(
ErrorCode::Internal,
@ -176,7 +176,7 @@ impl UserManager {
session.user_id,
&user_awareness_id.to_string(),
CollabType::UserAwareness,
raw_data,
DocStateSource::FromDocState(doc_state),
collab_db,
CollabBuilderConfig::default().sync_enable(true),
)