diff --git a/sync-server/build.rs b/sync-server/build.rs index 25c39362..d5068697 100644 --- a/sync-server/build.rs +++ b/sync-server/build.rs @@ -1,3 +1,4 @@ +// generated by `sqlx migrate build-script` fn main() { // trigger recompilation when a new migration is added println!("cargo:rerun-if-changed=migrations"); diff --git a/sync-server/config-e2e.yml b/sync-server/config-e2e.yml index 03b860b7..7b43ced9 100644 --- a/sync-server/config-e2e.yml +++ b/sync-server/config-e2e.yml @@ -1,5 +1,5 @@ database: - databases_directory_path: /host/tmp/vaultlink-e2e-databases + databases_directory_path: databases max_connections_per_vault: 8 cursor_timeout: 1m server: diff --git a/sync-server/src/app_state/cursors.rs b/sync-server/src/app_state/cursors.rs index 6bde3613..d3ea0602 100644 --- a/sync-server/src/app_state/cursors.rs +++ b/sync-server/src/app_state/cursors.rs @@ -18,6 +18,8 @@ use crate::{ errors::SyncServerError, }; +const CURSOR_CLEANUP_INTERVAL: Duration = Duration::from_secs(1); + #[derive(Clone, Debug)] pub struct Cursors { config: DatabaseConfig, @@ -76,7 +78,7 @@ impl Cursors { tokio::spawn(async move { loop { tokio::select! { - () = tokio::time::sleep(Duration::from_secs(1)) => { + () = tokio::time::sleep(CURSOR_CLEANUP_INTERVAL) => { self.remove_expired_cursors().await?; } Ok(()) = shutdown.changed() => break, diff --git a/sync-server/src/app_state/websocket/models.rs b/sync-server/src/app_state/websocket/models.rs index eb6c956a..8a8d42cc 100644 --- a/sync-server/src/app_state/websocket/models.rs +++ b/sync-server/src/app_state/websocket/models.rs @@ -58,15 +58,6 @@ pub struct CursorPositionFromServer { pub clients: Vec, } -// One committed version. Non-delete updates are broadcast to every -// connected client *except* the device that authored them — that -// device already has the new state via its HTTP response. Deletes are -// broadcast to every client including the author: the author keeps -// the document in its sync queue until this receipt arrives so a late -// remote update can't sneak in between the HTTP response and the -// queue cleanup. The server also emits these one-at-a-time to catch -// up a freshly-connected client on versions committed while it was -// offline, in ascending `vault_update_id` order. #[derive(TS, Serialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct WebSocketVaultUpdate { diff --git a/sync-server/src/app_state/websocket/utils.rs b/sync-server/src/app_state/websocket/utils.rs index a1e824b7..834684bb 100644 --- a/sync-server/src/app_state/websocket/utils.rs +++ b/sync-server/src/app_state/websocket/utils.rs @@ -51,6 +51,9 @@ pub fn get_authenticated_handshake( /// vault send lock; commits past the cursor are then delivered solely /// through the broadcast channel (filtered by the same cursor on the /// receive side), so every committed update is delivered exactly once. +/// We could've used a read transaction but that would've meant all other +/// clients would need to wait for the new client to catch up before +/// sending any updates. pub async fn get_unseen_documents( state: &AppState, vault_id: &VaultId,