diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index 1307dd0de2..46072e884c 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -1559,10 +1559,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.4" plugin_platform_interface: dependency: "direct dev" description: @@ -1989,10 +1989,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.2.0" string_validator: dependency: "direct main" description: @@ -2311,10 +2311,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.1" watcher: dependency: transitive description: diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 57035986b3..d4b0b2fa62 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -172,7 +172,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bincode", @@ -192,7 +192,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bytes", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "again", "anyhow", @@ -889,7 +889,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "collab-entity", "collab-rt-entity", @@ -902,7 +902,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "futures-channel", "futures-util", @@ -976,7 +976,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -1001,7 +1001,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "async-trait", @@ -1031,7 +1031,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -1051,7 +1051,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "bytes", @@ -1070,7 +1070,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -1113,7 +1113,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "async-stream", @@ -1151,7 +1151,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bincode", @@ -1176,7 +1176,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "async-trait", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "collab", @@ -1573,7 +1573,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -2209,6 +2209,7 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", + "moka", "nanoid", "protobuf", "rayon", @@ -3127,7 +3128,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "futures-util", @@ -3144,7 +3145,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -3576,7 +3577,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bytes", @@ -4250,6 +4251,30 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "moka" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener", + "futures-util", + "once_cell", + "parking_lot 0.12.1", + "quanta", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + [[package]] name = "multimap" version = "0.8.3" @@ -5332,6 +5357,21 @@ dependencies = [ "psl-types", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quick-xml" version = "0.28.2" @@ -5458,6 +5498,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "raw-cpuid" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" +dependencies = [ + "bitflags 2.4.0", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -6180,7 +6229,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -6548,6 +6597,12 @@ dependencies = [ "version-compare 0.1.1", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tantivy" version = "0.22.0" @@ -7419,6 +7474,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + [[package]] name = "try-lock" version = "0.2.4" diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 1c162e27e7..8fe2714950 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -58,7 +58,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "96896101d476426a8c41deceeec63cb4f2b09a1d" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "031cd7a15685ba5a0fc19feb75a740f7cb289996" } [dependencies] serde_json.workspace = true @@ -119,13 +119,13 @@ custom-protocol = ["tauri/custom-protocol"] # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } # Working directory: frontend # To update the commit ID, run: diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index 1f2d405daa..adecb583e1 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bincode", @@ -183,7 +183,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bytes", @@ -811,7 +811,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "again", "anyhow", @@ -863,7 +863,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "collab-entity", "collab-rt-entity", @@ -876,7 +876,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "futures-channel", "futures-util", @@ -959,7 +959,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -984,7 +984,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "async-trait", @@ -1014,7 +1014,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -1034,7 +1034,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "bytes", @@ -1053,7 +1053,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -1096,7 +1096,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "async-stream", @@ -1134,7 +1134,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bincode", @@ -1159,7 +1159,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "async-trait", @@ -1176,7 +1176,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "collab", @@ -1438,7 +1438,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.10", - "phf 0.11.2", + "phf 0.8.0", "smallvec", ] @@ -1563,7 +1563,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -2239,6 +2239,7 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", + "moka", "nanoid", "protobuf", "rayon", @@ -3194,7 +3195,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "futures-util", @@ -3211,7 +3212,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -3648,7 +3649,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bytes", @@ -4312,6 +4313,30 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "moka" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener", + "futures-util", + "once_cell", + "parking_lot 0.12.1", + "quanta", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + [[package]] name = "multimap" version = "0.8.3" @@ -5394,6 +5419,21 @@ dependencies = [ "psl-types", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quick-xml" version = "0.31.0" @@ -5520,6 +5560,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "raw-cpuid" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -6244,7 +6293,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -6621,6 +6670,12 @@ dependencies = [ "version-compare 0.2.0", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tantivy" version = "0.22.0" @@ -7563,6 +7618,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + [[package]] name = "try-lock" version = "0.2.5" diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index bfe89ee9b2..f6ce4a15f4 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -57,7 +57,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "96896101d476426a8c41deceeec63cb4f2b09a1d" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "031cd7a15685ba5a0fc19feb75a740f7cb289996" } [dependencies] serde_json.workspace = true @@ -117,13 +117,13 @@ custom-protocol = ["tauri/custom-protocol"] # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } # Working directory: frontend # To update the commit ID, run: diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index b827e795a9..a51c1628d2 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bincode", @@ -183,7 +183,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bytes", @@ -729,7 +729,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "again", "anyhow", @@ -781,7 +781,7 @@ dependencies = [ [[package]] name = "client-api-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "collab-entity", "collab-rt-entity", @@ -794,7 +794,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "futures-channel", "futures-util", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -862,7 +862,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "async-trait", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -912,7 +912,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "bytes", @@ -931,7 +931,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "arc-swap", @@ -974,7 +974,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "async-stream", @@ -1012,7 +1012,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bincode", @@ -1037,7 +1037,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "async-trait", @@ -1054,7 +1054,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354#71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e#41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" dependencies = [ "anyhow", "collab", @@ -1397,7 +1397,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -2037,6 +2037,7 @@ dependencies = [ "lazy_static", "lib-dispatch", "lib-infra", + "moka", "nanoid", "protobuf", "rayon", @@ -2806,7 +2807,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "futures-util", @@ -2823,7 +2824,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -3188,7 +3189,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "bytes", @@ -3729,6 +3730,30 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "moka" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener", + "futures-util", + "once_cell", + "parking_lot 0.12.1", + "quanta", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + [[package]] name = "multimap" version = "0.8.3" @@ -4619,6 +4644,21 @@ dependencies = [ "psl-types", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quickcheck" version = "1.0.3" @@ -4786,6 +4826,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "raw-cpuid" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" +dependencies = [ + "bitflags 2.4.0", +] + [[package]] name = "rayon" version = "1.10.0" @@ -5065,6 +5114,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.31" @@ -5403,7 +5461,7 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=96896101d476426a8c41deceeec63cb4f2b09a1d#96896101d476426a8c41deceeec63cb4f2b09a1d" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=031cd7a15685ba5a0fc19feb75a740f7cb289996#031cd7a15685ba5a0fc19feb75a740f7cb289996" dependencies = [ "anyhow", "app-error", @@ -5722,6 +5780,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tantivy" version = "0.22.0" @@ -6391,6 +6455,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + [[package]] name = "try-lock" version = "0.2.4" diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index e842d32f98..43405e53c5 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -105,8 +105,8 @@ dashmap = "6.0.1" # Run the script.add_workspace_members: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "96896101d476426a8c41deceeec63cb4f2b09a1d" } -client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "96896101d476426a8c41deceeec63cb4f2b09a1d" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "031cd7a15685ba5a0fc19feb75a740f7cb289996" } +client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "031cd7a15685ba5a0fc19feb75a740f7cb289996" } [profile.dev] opt-level = 0 @@ -141,13 +141,13 @@ rocksdb = { git = "https://github.com/rust-rocksdb/rust-rocksdb", rev = "1710120 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "71c5bd32ddb72252e8f8eddfd4f5ce75ecd31354" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "41e0b9ab59d3f95c4f3b8af64ca05629f76fad5e" } # Working directory: frontend # To update the commit ID, run: diff --git a/frontend/rust-lib/flowy-database2/Cargo.toml b/frontend/rust-lib/flowy-database2/Cargo.toml index a6a356795e..9c97bf39aa 100644 --- a/frontend/rust-lib/flowy-database2/Cargo.toml +++ b/frontend/rust-lib/flowy-database2/Cargo.toml @@ -51,6 +51,7 @@ strum_macros = "0.25" validator = { workspace = true, features = ["derive"] } tokio-util.workspace = true tokio-retry = "0.3" +moka = { version = "0.12.8", features = ["future"] } [dev-dependencies] event-integration-test = { path = "../event-integration-test", default-features = false } diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index cd278734c2..0ca12e2c50 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -2,7 +2,7 @@ use collab_database::rows::{Cell, RowId}; use lib_infra::box_any::BoxAny; use std::sync::{Arc, Weak}; use tokio::sync::oneshot; -use tracing::{error, info, trace}; +use tracing::{error, info}; use flowy_error::{FlowyError, FlowyResult}; use lib_dispatch::prelude::{af_spawn, data_result_ok, AFPluginData, AFPluginState, DataResult}; @@ -38,14 +38,17 @@ pub(crate) async fn get_database_data_handler( let database_editor = manager .get_or_init_database_editor(&database_id, Some(view_id.as_ref())) .await?; + let start = std::time::Instant::now(); let data = database_editor .open_database_view(view_id.as_ref(), None) .await?; - trace!( - "layout: {:?}, rows: {}, fields: {}", + info!( + "[Database]: {} layout: {:?}, rows: {}, fields: {}, cost time: {} milliseconds", + database_id, data.layout_type, data.rows.len(), - data.fields.len() + data.fields.len(), + start.elapsed().as_millis() ); data_result_ok(data) } @@ -80,8 +83,7 @@ pub(crate) async fn open_database_handler( let database_id = manager .get_database_id_with_view_id(view_id.as_ref()) .await?; - let mut editors = manager.editors.lock().await; - let _ = manager.open_database(&database_id, &mut editors).await?; + let _ = manager.open_database(&database_id).await?; Ok(()) } diff --git a/frontend/rust-lib/flowy-database2/src/manager.rs b/frontend/rust-lib/flowy-database2/src/manager.rs index 5d56c88148..a4abdefaf7 100644 --- a/frontend/rust-lib/flowy-database2/src/manager.rs +++ b/frontend/rust-lib/flowy-database2/src/manager.rs @@ -226,25 +226,22 @@ impl DatabaseManager { database_id: &str, _database_view_id: Option<&str>, ) -> FlowyResult> { - let mut editors = self.editors.lock().await; - if let Some(editor) = editors.get(database_id).cloned() { + if let Some(editor) = self.editors.lock().await.get(database_id).cloned() { return Ok(editor); } - - let editor = self.open_database(database_id, &mut editors).await?; - drop(editors); + let editor = self.open_database(database_id).await?; Ok(editor) } #[instrument(level = "trace", skip_all, err)] - pub async fn open_database( - &self, - database_id: &str, - editors: &mut DatabaseEditorMap, - ) -> FlowyResult> { + pub async fn open_database(&self, database_id: &str) -> FlowyResult> { let workspace_database = self.workspace_database()?; if let Some(database_editor) = self.removing_editor.lock().await.remove(database_id) { - editors.insert(database_id.to_string(), database_editor.clone()); + self + .editors + .lock() + .await + .insert(database_id.to_string(), database_editor.clone()); return Ok(database_editor); } @@ -253,7 +250,7 @@ impl DatabaseManager { // hasn't finished syncing yet. In such cases, get_or_create_database will return None. // The workaround is to add a retry mechanism to attempt fetching the database again. let database = Retry::spawn( - ExponentialBackoff::from_millis(2).factor(1000).take(3), + ExponentialBackoff::from_millis(3).factor(1000).take(2), || async { trace!("retry to open database:{}", database_id); let database = workspace_database @@ -275,7 +272,11 @@ impl DatabaseManager { ) .await?; - editors.insert(database_id.to_string(), editor.clone()); + self + .editors + .lock() + .await + .insert(database_id.to_string(), editor.clone()); Ok(editor) } @@ -285,10 +286,9 @@ impl DatabaseManager { let lock = self.workspace_database()?; let workspace_database = lock.read().await; if let Some(database_id) = workspace_database.get_database_id_with_view_id(view_id) { - let mut editors = self.editors.lock().await; - if editors.get(&database_id).is_none() { - let _ = self.open_database(&database_id, &mut editors).await?; - drop(editors); + let is_not_exist = self.editors.lock().await.get(&database_id).is_none(); + if is_not_exist { + let _ = self.open_database(&database_id).await?; } } Ok(()) @@ -302,12 +302,11 @@ impl DatabaseManager { if let Some(database_id) = database_id { let mut editors = self.editors.lock().await; let mut should_remove = false; - if let Some(editor) = editors.get(&database_id) { editor.close_view(view_id).await; // when there is no opening views, mark the database to be removed. trace!( - "{} has {} opening views", + "[Database]: {} has {} opening views", database_id, editor.num_of_opening_views().await ); @@ -315,7 +314,10 @@ impl DatabaseManager { } if should_remove { - if let Some(editor) = editors.remove(&database_id) { + let editor = editors.remove(&database_id); + drop(editors); + + if let Some(editor) = editor { editor.close_database().await; self .removing_editor @@ -760,6 +762,13 @@ impl DatabaseCollabService for WorkspaceDatabaseCollabServiceImpl { ) -> Result { let object = self.build_collab_object(object_id, collab_type.clone())?; let data_source = if self.persistence.is_collab_exist(object_id) { + if encoded_collab.is_some() { + error!( + "build collab: {}:{} with both local and remote encode collab", + collab_type, object_id + ); + } + CollabPersistenceImpl { persistence: Some(self.persistence.clone()), } diff --git a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs index de3db8e2e8..d9b56f9f4f 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs @@ -21,13 +21,14 @@ use crate::services::share::csv::{CSVExport, CSVFormat}; use crate::services::sort::Sort; use crate::utils::cache::AnyTypeCache; use crate::DatabaseUser; -use arc_swap::ArcSwap; +use arc_swap::{ArcSwap, ArcSwapOption}; use async_trait::async_trait; +use collab::core::collab_plugin::CollabPluginType; use collab::lock::RwLock; use collab_database::database::Database; use collab_database::entity::DatabaseView; use collab_database::fields::{Field, TypeOptionData}; -use collab_database::rows::{Cell, Cells, DatabaseRow, Row, RowCell, RowDetail, RowId}; +use collab_database::rows::{Cell, Cells, DatabaseRow, Row, RowCell, RowDetail, RowId, RowUpdate}; use collab_database::views::{ DatabaseLayout, FilterMap, LayoutSetting, OrderObjectPosition, RowOrder, }; @@ -40,8 +41,9 @@ use lib_infra::box_any::BoxAny; use lib_infra::priority_task::TaskDispatcher; use lib_infra::util::timestamp; use std::collections::HashMap; -use std::sync::Arc; +use std::sync::{Arc, Weak}; use std::time::Duration; +use tokio::select; use tokio::sync::oneshot::Sender; use tokio::sync::RwLock as TokioRwLock; use tokio::sync::{broadcast, oneshot}; @@ -61,6 +63,8 @@ pub struct DatabaseEditor { is_opening: ArcSwap, opening_ret_txs: Arc>>, database_cancellation: Arc>>, + un_finalized_rows_cancellation: Arc>, + finalized_rows: Arc>>>, } impl DatabaseEditor { @@ -70,6 +74,15 @@ impl DatabaseEditor { task_scheduler: Arc>, collab_builder: Arc, ) -> FlowyResult> { + let finalized_rows: moka::future::Cache>> = + moka::future::Cache::builder() + .max_capacity(50) + .async_eviction_listener(|key, value, _| { + Box::pin(async move { + database_row_evict_listener(key, value).await; + }) + }) + .build(); let notification_sender = Arc::new(DebounceNotificationSender::new(200)); let cell_cache = AnyTypeCache::::new(); let database_id = database.read().await.get_database_id(); @@ -121,6 +134,8 @@ impl DatabaseEditor { is_opening: Default::default(), opening_ret_txs: Arc::new(Default::default()), database_cancellation, + un_finalized_rows_cancellation: Arc::new(Default::default()), + finalized_rows: Arc::new(finalized_rows), }); observe_block_event(&database_id, &this).await; observe_view_change(&database_id, &this).await; @@ -128,7 +143,7 @@ impl DatabaseEditor { } pub async fn close_view(&self, view_id: &str) { - self.database_views.close_view(view_id).await; + self.database_views.remove_view(view_id).await; } pub async fn get_row_ids(&self) -> Vec { @@ -609,15 +624,12 @@ impl DatabaseEditor { .await; if !updated_cells.is_empty() { self - .database - .write() - .await .update_row(row.id, |row| { row .set_last_modified(timestamp()) .set_cells(Cells::from(updated_cells)); }) - .await; + .await?; } let to_row = if to_row.is_some() { @@ -765,19 +777,27 @@ impl DatabaseEditor { .with_context(format!("The row:{} in database not found", row_id)) })?; - let collab_object = self.collab_builder.collab_object( - &self.user.workspace_id()?, - self.user.user_id()?, - row_id, - CollabType::DatabaseRow, - )?; + let is_finalized = self.finalized_rows.get(row_id.as_str()).await.is_some(); + if !is_finalized { + trace!("[Database]: finalize database row: {}", row_id); + let collab_object = self.collab_builder.collab_object( + &self.user.workspace_id()?, + self.user.user_id()?, + row_id, + CollabType::DatabaseRow, + )?; - if let Err(err) = self.collab_builder.finalize( - collab_object, - CollabBuilderConfig::default(), - database_row.clone(), - ) { - error!("Failed to init database row: {}", err); + if let Err(err) = self.collab_builder.finalize( + collab_object, + CollabBuilderConfig::default(), + database_row.clone(), + ) { + error!("Failed to init database row: {}", err); + } + self + .finalized_rows + .insert(row_id.to_string(), Arc::downgrade(&database_row)) + .await; } Ok(database_row) @@ -939,9 +959,6 @@ impl DatabaseEditor { // Get the old row before updating the cell. It would be better to get the old cell let old_row = self.get_row(view_id, row_id).await; self - .database - .write() - .await .update_row(row_id.clone(), |row_update| { row_update .set_last_modified(timestamp()) @@ -949,7 +966,7 @@ impl DatabaseEditor { cell_update.insert(field_id, new_cell); }); }) - .await; + .await?; self .did_update_row(view_id, row_id, field_id, old_row) @@ -958,20 +975,31 @@ impl DatabaseEditor { Ok(()) } + pub async fn update_row(&self, row_id: RowId, modify: F) -> FlowyResult<()> + where + F: FnOnce(RowUpdate), + { + if self.finalized_rows.get(row_id.as_str()).await.is_none() { + info!( + "[Database Row]: row:{} is not finalized when editing, init it", + row_id + ); + self.init_database_row(&row_id).await?; + } + self.database.write().await.update_row(row_id, modify).await; + Ok(()) + } + pub async fn clear_cell(&self, view_id: &str, row_id: RowId, field_id: &str) -> FlowyResult<()> { // Get the old row before updating the cell. It would be better to get the old cell let old_row = self.get_row(view_id, &row_id).await; - self - .database - .write() - .await .update_row(row_id.clone(), |row_update| { row_update.update_cells(|cell_update| { cell_update.clear(field_id); }); }) - .await; + .await?; self .did_update_row(view_id, &row_id, field_id, old_row) @@ -1364,7 +1392,30 @@ impl DatabaseEditor { } pub async fn close_database(&self) { - info!("close database editor: {}", self.database_id); + info!("[Database]: {} close", self.database_id); + let token = CancellationToken::new(); + let cloned_finalized_rows = self.finalized_rows.clone(); + self + .un_finalized_rows_cancellation + .store(Some(Arc::new(token.clone()))); + tokio::spawn(async move { + // Using select! to concurrently run two asynchronous futures: + // 1. Wait for 30 seconds, then invalidate all the finalized rows. + // 2. If the cancellation token (`token`) is triggered before the 30 seconds expire, + // cancel the invalidation action and do nothing. + select! { + _ = tokio::time::sleep(Duration::from_secs(30)) => { + for (row_id, row) in cloned_finalized_rows.iter() { + remove_row_sync_plugin(row_id.as_str(), row).await; + } + cloned_finalized_rows.invalidate_all(); + }, + _ = token.cancelled() => { + trace!("Invalidate action cancelled"); + } + } + }); + let cancellation = self.database_cancellation.read().await; if let Some(cancellation) = &*cancellation { info!("Cancel database operation"); @@ -1382,6 +1433,10 @@ impl DatabaseEditor { view_id: &str, notify_finish: Option>, ) -> FlowyResult { + if let Some(un_finalized_rows_token) = self.un_finalized_rows_cancellation.load_full() { + un_finalized_rows_token.cancel(); + } + let (tx, rx) = oneshot::channel(); self.opening_ret_txs.write().await.push(tx); // Check if the database is currently being opened @@ -1429,11 +1484,10 @@ impl DatabaseEditor { ); let view_editor = self.database_views.get_or_init_view_editor(view_id).await?; - let should_wait = notify_finish.is_some() || row_metas.len() < 10; + let blocking_read = notify_finish.is_some() || row_metas.len() < 50; let (tx, rx) = oneshot::channel(); - self.async_load_rows(view_editor, Some(tx), new_token); - if should_wait { - info!("[Database]: block until all rows are loaded"); + self.async_load_rows(view_editor, Some(tx), new_token, blocking_read); + if blocking_read { if let Ok(rows) = rx.await { row_metas = rows .into_iter() @@ -1455,9 +1509,6 @@ impl DatabaseEditor { }); // Mark that the opening process is complete self.is_opening.store(Arc::new(false)); - // Clear cancellation token - self.database_cancellation.write().await.take(); - // Collect all waiting tasks and send the result let txs = std::mem::take(&mut *self.opening_ret_txs.write().await); for tx in txs { @@ -1477,8 +1528,12 @@ impl DatabaseEditor { view_editor: Arc, notify_finish: Option>>>, new_token: CancellationToken, + blocking_read: bool, ) { - trace!("[Database]: start loading rows"); + trace!( + "[Database]: start loading rows, blocking: {}", + blocking_read + ); let cloned_database = Arc::downgrade(&self.database); tokio::spawn(async move { let apply_filter_and_sort = @@ -1491,12 +1546,20 @@ impl DatabaseEditor { if view_editor.has_filters().await { trace!("[Database]: filtering rows:{}", loaded_rows.len()); - view_editor.v_filter_rows_and_notify(&mut loaded_rows).await; + if blocking_read { + loaded_rows = view_editor.v_filter_rows(loaded_rows).await; + } else { + view_editor.v_filter_rows_and_notify(&mut loaded_rows).await; + } } if view_editor.has_sorts().await { trace!("[Database]: sorting rows:{}", loaded_rows.len()); - view_editor.v_sort_rows_and_notify(&mut loaded_rows).await; + if blocking_read { + view_editor.v_sort_rows(&mut loaded_rows).await; + } else { + view_editor.v_sort_rows_and_notify(&mut loaded_rows).await; + } } loaded_rows @@ -1549,7 +1612,11 @@ impl DatabaseEditor { } drop(row_orders); - info!("[Database]: Finish loading all rows: {}", loaded_rows.len()); + info!( + "[Database]: Finish loading all rows: {}, blocking: {}", + loaded_rows.len(), + blocking_read + ); let loaded_rows = apply_filter_and_sort(loaded_rows, view_editor).await; if let Some(notify_finish) = notify_finish { let _ = notify_finish.send(loaded_rows); @@ -2142,3 +2209,20 @@ fn notify_did_update_database_field(database: &Database, field_id: &str) -> Flow } Ok(()) } + +async fn database_row_evict_listener(key: Arc, row: Weak>) { + remove_row_sync_plugin(key.as_str(), row).await +} + +async fn remove_row_sync_plugin(row_id: &str, row: Weak>) { + if let Some(row) = row.upgrade() { + let should_remove = row.read().await.has_cloud_plugin(); + if should_remove { + trace!("[Database]: un-finalize row: {}", row_id); + row + .write() + .await + .remove_plugins_for_types(vec![CollabPluginType::CloudStorage]); + } + } +} diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs index ac958535f6..d907776d40 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_editor.rs @@ -216,8 +216,8 @@ impl DatabaseViewEditor { if !is_move_row || !is_local_change { if let Some(controller) = self.group_controller.write().await.as_mut() { - let mut rows = vec![Arc::new(row.clone())]; - self.v_filter_rows(&mut rows).await; + let rows = vec![Arc::new(row.clone())]; + let mut rows = self.v_filter_rows(rows).await; if let Some(row) = rows.pop() { let changesets = controller.did_create_row(&row, index as usize); for changeset in changesets { @@ -270,8 +270,8 @@ impl DatabaseViewEditor { .await; if let Some(field) = field { - let mut rows = vec![Arc::new(row.clone())]; - self.v_filter_rows(&mut rows).await; + let rows = vec![Arc::new(row.clone())]; + let mut rows = self.v_filter_rows(rows).await; if let Some(row) = rows.pop() { let result = controller.did_update_group_row(old_row, &row, &field); @@ -312,7 +312,7 @@ impl DatabaseViewEditor { .await; } - pub async fn v_filter_rows(&self, rows: &mut Vec>) { + pub async fn v_filter_rows(&self, rows: Vec>) -> Vec> { self.filter_controller.filter_rows(rows).await } @@ -336,8 +336,8 @@ impl DatabaseViewEditor { #[instrument(level = "info", skip(self))] pub async fn v_get_all_rows(&self) -> Vec> { let row_orders = self.delegate.get_all_row_orders(&self.view_id).await; - let mut rows = self.delegate.get_all_rows(&self.view_id, row_orders).await; - self.v_filter_rows(&mut rows).await; + let rows = self.delegate.get_all_rows(&self.view_id, row_orders).await; + let mut rows = self.v_filter_rows(rows).await; self.v_sort_rows(&mut rows).await; rows } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs index bb1f4a0dfc..97e7a91cb0 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_group.rs @@ -98,9 +98,9 @@ impl GroupControllerDelegate for GroupControllerDelegateImpl { async fn get_all_rows(&self, view_id: &str) -> Vec> { let row_orders = self.delegate.get_all_row_orders(view_id).await; - let mut rows = self.delegate.get_all_rows(view_id, row_orders).await; - self.filter_controller.filter_rows(&mut rows).await; - rows + let rows = self.delegate.get_all_rows(view_id, row_orders).await; + + self.filter_controller.filter_rows(rows).await } } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs index 8b4b9dec94..12ff919e3c 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/view_sort.rs @@ -62,14 +62,14 @@ impl SortDelegate for DatabaseViewSortDelegateImpl { async fn get_rows(&self, view_id: &str) -> Vec> { let view_id = view_id.to_string(); let row_orders = self.delegate.get_all_row_orders(&view_id).await; - let mut rows = self.delegate.get_all_rows(&view_id, row_orders).await; - self.filter_controller.filter_rows(&mut rows).await; - rows + let rows = self.delegate.get_all_rows(&view_id, row_orders).await; + + self.filter_controller.filter_rows(rows).await } async fn filter_row(&self, row: &Row) -> bool { - let mut rows = vec![Arc::new(row.clone())]; - self.filter_controller.filter_rows(&mut rows).await; + let rows = vec![Arc::new(row.clone())]; + let rows = self.filter_controller.filter_rows(rows).await; !rows.is_empty() } diff --git a/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs b/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs index 5393e9d44a..278eb1f7d7 100644 --- a/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs +++ b/frontend/rust-lib/flowy-database2/src/services/database_view/views.rs @@ -37,7 +37,7 @@ impl DatabaseViews { }) } - pub async fn close_view(&self, view_id: &str) { + pub async fn remove_view(&self, view_id: &str) { let mut lock_guard = self.view_editors.write().await; if let Some(view) = lock_guard.remove(view_id) { view.close().await; diff --git a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs index cad414f979..521c87168a 100644 --- a/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs +++ b/frontend/rust-lib/flowy-database2/src/services/filter/controller.rs @@ -10,6 +10,8 @@ use collab_database::rows::{Cell, Cells, Row, RowDetail, RowId}; use dashmap::DashMap; use flowy_error::FlowyResult; use lib_infra::priority_task::{QualityOfService, Task, TaskContent, TaskDispatcher}; +use rayon::prelude::*; + use serde::{Deserialize, Serialize}; use tokio::sync::RwLock as TokioRwLock; use tracing::{error, trace}; @@ -358,22 +360,23 @@ impl FilterController { pub async fn filter_rows_and_notify(&self, rows: &mut Vec>) -> FlowyResult<()> { let filters = self.filters.read().await; let field_by_field_id = self.get_field_map().await; - let mut visible_rows = vec![]; - let mut invisible_rows = vec![]; - for (index, row) in rows.iter_mut().enumerate() { - if filter_row( - row, - &self.result_by_row_id, - &field_by_field_id, - &self.cell_cache, - &filters, - ) { - let row_meta = RowMetaPB::from(row.as_ref()); - visible_rows.push(InsertedRowPB::new(row_meta).with_index(index as i32)) - } else { - invisible_rows.push(row.id.clone()); - } - } + let (visible_rows, invisible_rows): (Vec<_>, Vec<_>) = + rows.par_iter().enumerate().partition_map(|(index, row)| { + if filter_row( + row, + &self.result_by_row_id, + &field_by_field_id, + &self.cell_cache, + &filters, + ) { + let row_meta = RowMetaPB::from(row.as_ref()); + // Visible rows go into the left partition + rayon::iter::Either::Left(InsertedRowPB::new(row_meta).with_index(index as i32)) + } else { + // Invisible rows (just IDs) go into the right partition + rayon::iter::Either::Right(row.id.clone()) + } + }); let len = rows.len(); rows.retain(|row| !invisible_rows.iter().any(|id| id == &row.id)); @@ -390,10 +393,10 @@ impl FilterController { Ok(()) } - pub async fn filter_rows(&self, rows: &mut Vec>) { + pub async fn filter_rows(&self, mut rows: Vec>) -> Vec> { let filters = self.filters.read().await; let field_by_field_id = self.get_field_map().await; - rows.iter().for_each(|row| { + rows.par_iter().for_each(|row| { let _ = filter_row( row, &self.result_by_row_id, @@ -410,6 +413,7 @@ impl FilterController { .map(|result| *result) .unwrap_or(false) }); + rows } async fn get_field_map(&self) -> HashMap { diff --git a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs index 0f755caedb..15cd373703 100644 --- a/frontend/rust-lib/flowy-server/src/af_cloud/server.rs +++ b/frontend/rust-lib/flowy-server/src/af_cloud/server.rs @@ -5,6 +5,7 @@ use std::time::Duration; use crate::af_cloud::define::ServerUser; use anyhow::Error; +use arc_swap::ArcSwap; use client_api::collab_sync::ServerCollabMessage; use client_api::entity::ai_dto::AIModel; use client_api::entity::UserMessage; @@ -28,10 +29,11 @@ use lib_dispatch::prelude::af_spawn; use rand::Rng; use semver::Version; use tokio::select; -use tokio::sync::{watch, Mutex}; +use tokio::sync::watch; +use tokio::task::JoinHandle; use tokio_stream::wrappers::WatchStream; use tokio_util::sync::CancellationToken; -use tracing::{error, event, info, warn}; +use tracing::{error, info, warn}; use uuid::Uuid; use crate::af_cloud::impls::{ @@ -91,15 +93,8 @@ impl AppFlowyCloudServer { ); let ws_client = Arc::new(ws_client); let api_client = Arc::new(api_client); - let ws_connect_cancellation_token = Arc::new(Mutex::new(CancellationToken::new())); - spawn_ws_conn( - token_state_rx, - &ws_client, - ws_connect_cancellation_token, - &api_client, - &enable_sync, - ); + spawn_ws_conn(token_state_rx, &ws_client, &api_client, &enable_sync); Self { config, client: api_client, @@ -292,14 +287,15 @@ impl AppFlowyServer for AppFlowyCloudServer { fn spawn_ws_conn( mut token_state_rx: TokenStateReceiver, ws_client: &Arc, - conn_cancellation_token: Arc>, api_client: &Arc, enable_sync: &Arc, ) { let weak_ws_client = Arc::downgrade(ws_client); let weak_api_client = Arc::downgrade(api_client); let enable_sync = enable_sync.clone(); - let cloned_conn_cancellation_token = conn_cancellation_token.clone(); + + let cancellation_token = Arc::new(ArcSwap::new(Arc::new(CancellationToken::new()))); + let cloned_cancellation_token = cancellation_token.clone(); af_spawn(async move { if let Some(ws_client) = weak_ws_client.upgrade() { @@ -310,7 +306,7 @@ fn spawn_ws_conn( ConnectState::PingTimeout | ConnectState::Lost => { // Try to reconnect if the connection is timed out. if weak_api_client.upgrade().is_some() && enable_sync.load(Ordering::SeqCst) { - attempt_reconnect(&ws_client, 2, &cloned_conn_cancellation_token).await; + attempt_reconnect(&ws_client, 2, &cloned_cancellation_token).await; } }, ConnectState::Unauthorized => { @@ -336,7 +332,7 @@ fn spawn_ws_conn( match token_state { TokenState::Refresh => { if let Some(ws_client) = weak_ws_client.upgrade() { - attempt_reconnect(&ws_client, 5, &conn_cancellation_token).await; + attempt_reconnect(&ws_client, 5, &cancellation_token).await; } }, TokenState::Invalid => { @@ -359,34 +355,29 @@ fn spawn_ws_conn( async fn attempt_reconnect( ws_client: &Arc, minimum_delay_in_secs: u64, - conn_cancellation_token: &Arc>, -) { - // Cancel the previous reconnection attempt - let mut cancel_token_lock = conn_cancellation_token.lock().await; - cancel_token_lock.cancel(); - + cancellation_token: &Arc>, +) -> JoinHandle<()> { + cancellation_token.load_full().cancel(); let new_cancel_token = CancellationToken::new(); - *cancel_token_lock = new_cancel_token.clone(); - drop(cancel_token_lock); + cancellation_token.store(Arc::new(new_cancel_token.clone())); - // randomness in the reconnection attempts to avoid thundering herd problem let delay_seconds = rand::thread_rng().gen_range(minimum_delay_in_secs..10); - let ws_client = ws_client.clone(); + let ws_client_clone = ws_client.clone(); tokio::spawn(async move { select! { - _ = new_cancel_token.cancelled() => { - event!( - tracing::Level::TRACE, - "🟢websocket reconnection attempt cancelled." - ); - }, - _ = tokio::time::sleep(Duration::from_secs(delay_seconds)) => { - if let Err(e) = ws_client.connect().await { - error!("Failed to reconnect websocket: {}", e); + // If the new cancellation token is triggered, log cancellation + _ = new_cancel_token.cancelled() => { + tracing::trace!("🟢 websocket reconnection attempt cancelled."); + }, + _ = tokio::time::sleep(Duration::from_secs(delay_seconds)) => { + if let Err(e) = ws_client_clone.connect().await { + error!("❌ Failed to reconnect websocket: {}", e); + } else { + info!("✅ Reconnected websocket successfully."); + } } - } } - }); + }) } pub trait AFServer: Send + Sync + 'static { diff --git a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs index 8a1f1d0e31..4746014d14 100644 --- a/frontend/rust-lib/lib-dispatch/src/dispatcher.rs +++ b/frontend/rust-lib/lib-dispatch/src/dispatcher.rs @@ -60,6 +60,7 @@ pub type BoxFutureCallback = pub type BoxFutureCallback = Box AFBoxFuture<'static, ()> + Send + Sync + 'static>; +#[track_caller] pub fn af_spawn(future: T) -> tokio::task::JoinHandle where T: Future + Send + 'static,