no remote path chacnge
This commit is contained in:
parent
19d5dc1999
commit
17a1f4d060
16 changed files with 93 additions and 314 deletions
|
|
@ -20,24 +20,6 @@ pub mod models;
|
|||
#[error("Database is busy")]
|
||||
pub struct WriteBusyError;
|
||||
|
||||
/// Tells [`Database::insert_document_version`] which WebSocket events the
|
||||
/// just-committed version should produce. The caller is the only party
|
||||
/// with enough context to decide this (the DB layer has no access to
|
||||
/// "what the client sent" or "what the prior version looked like").
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct InsertBroadcast {
|
||||
/// Emit a `VaultUpdate` (filtered from the origin device). Set when
|
||||
/// the stored bytes differ from the prior version's bytes — i.e.
|
||||
/// peers need to pull new content.
|
||||
pub content_changed: bool,
|
||||
|
||||
/// Emit a `PathChange` (delivered to every client, origin included).
|
||||
/// Set when the stored path differs from the prior stored path *or*
|
||||
/// from the path the origin client sent — i.e. someone needs to
|
||||
/// reconcile a dedupe, rename, or first-rename-wins outcome.
|
||||
pub path_changed: bool,
|
||||
}
|
||||
|
||||
use sqlx::{
|
||||
Pool, Sqlite, pool::PoolConnection, sqlite::SqliteConnection, sqlite::SqlitePoolOptions,
|
||||
};
|
||||
|
|
@ -47,10 +29,7 @@ use uuid::fmt::Hyphenated;
|
|||
|
||||
use super::websocket::{
|
||||
broadcasts::Broadcasts,
|
||||
models::{
|
||||
WebSocketServerMessage, WebSocketServerMessageWithOrigin, WebSocketVaultPathChange,
|
||||
WebSocketVaultUpdate,
|
||||
},
|
||||
models::{WebSocketServerMessage, WebSocketServerMessageWithOrigin, WebSocketVaultUpdate},
|
||||
};
|
||||
use crate::config::database_config::DatabaseConfig;
|
||||
use crate::consts::IDLE_POOL_TIMEOUT;
|
||||
|
|
@ -693,7 +672,6 @@ impl Database {
|
|||
vault_id: &VaultId,
|
||||
version: &StoredDocumentVersion,
|
||||
mut transaction: WriteTransaction,
|
||||
broadcast: InsertBroadcast,
|
||||
) -> Result<()> {
|
||||
let document_id = version.document_id.as_hyphenated();
|
||||
let query = sqlx::query!(
|
||||
|
|
@ -739,39 +717,19 @@ impl Database {
|
|||
.await
|
||||
.context("Failed to commit transaction")?;
|
||||
|
||||
if broadcast.content_changed {
|
||||
// Content events are filtered out for the origin device — the
|
||||
// origin already has the content (or learns about the merge
|
||||
// via the HTTP response).
|
||||
self.broadcasts.send_document_update(
|
||||
vault_id.clone(),
|
||||
WebSocketServerMessageWithOrigin::with_origin(
|
||||
version.device_id.clone(),
|
||||
WebSocketServerMessage::VaultUpdate(WebSocketVaultUpdate {
|
||||
documents: vec![version.clone().into()],
|
||||
is_initial_sync: false,
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if broadcast.path_changed {
|
||||
// Path change events intentionally carry no origin so *every*
|
||||
// connected client (including the one that made the write)
|
||||
// receives them. The create/update HTTP response no longer
|
||||
// carries `relative_path`, so the origin device relies on this
|
||||
// event to learn the server-canonical path.
|
||||
self.broadcasts.send_document_update(
|
||||
vault_id.clone(),
|
||||
WebSocketServerMessageWithOrigin::new(WebSocketServerMessage::PathChange(
|
||||
WebSocketVaultPathChange {
|
||||
vault_update_id: version.vault_update_id,
|
||||
document_id: version.document_id,
|
||||
relative_path: version.relative_path.clone(),
|
||||
},
|
||||
)),
|
||||
);
|
||||
}
|
||||
// The broadcast is delivered to every connected client except the
|
||||
// author — the send task filters on `origin_device_id` (see
|
||||
// `websocket.rs`). The origin already has authoritative state
|
||||
// from the HTTP response that triggered this write.
|
||||
self.broadcasts.send_document_update(
|
||||
vault_id.clone(),
|
||||
WebSocketServerMessageWithOrigin::with_origin(
|
||||
version.device_id.clone(),
|
||||
WebSocketServerMessage::VaultUpdate(WebSocketVaultUpdate {
|
||||
document: version.clone().into(),
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,23 +58,15 @@ pub struct CursorPositionFromServer {
|
|||
pub clients: Vec<ClientCursors>,
|
||||
}
|
||||
|
||||
// Clients only get notified of other clients' updates through WebSocketVaultUpdate.
|
||||
// One committed version, broadcast to every connected client *except*
|
||||
// the device that authored it — that device already has the new state
|
||||
// via its HTTP response. 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 {
|
||||
pub documents: Vec<DocumentVersionWithoutContent>,
|
||||
pub is_initial_sync: bool,
|
||||
}
|
||||
|
||||
// Clients get notified of both their own and other clients' path changes through WebSocketVaultPathChange.
|
||||
// This is becuase we must absolutely order path updates as they may all depend on all previous updates.
|
||||
#[derive(TS, Serialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WebSocketVaultPathChange {
|
||||
#[ts(type = "number")]
|
||||
pub vault_update_id: VaultUpdateId,
|
||||
pub document_id: DocumentId,
|
||||
pub relative_path: String,
|
||||
pub document: DocumentVersionWithoutContent,
|
||||
}
|
||||
|
||||
#[derive(TS, Deserialize, Clone, Debug)]
|
||||
|
|
@ -90,10 +82,13 @@ pub enum WebSocketClientMessage {
|
|||
#[ts(export)]
|
||||
pub enum WebSocketServerMessage {
|
||||
VaultUpdate(WebSocketVaultUpdate),
|
||||
PathChange(WebSocketVaultPathChange),
|
||||
CursorPositions(CursorPositionFromServer),
|
||||
}
|
||||
|
||||
/// Broadcast envelope carrying the message plus the device that produced
|
||||
/// it. The per-recipient send task compares `origin_device_id` against
|
||||
/// its own device id to fill in `originates_from_self` before the message
|
||||
/// is serialized on the wire.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WebSocketServerMessageWithOrigin {
|
||||
pub origin_device_id: Option<DeviceId>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue