Bug fixes

This commit is contained in:
Andras Schmelczer 2026-03-15 13:27:18 +00:00
parent bbec7f14dd
commit df37e6c236
15 changed files with 632 additions and 157 deletions

View file

@ -55,7 +55,9 @@ pub async fn create_document(
.await
.map_err(server_error)?;
if let Some(existing) = existing {
info!("Found existing document with idempotency key `{idempotency_key}`, returning existing document");
info!(
"Found existing document with idempotency key `{idempotency_key}`, returning existing document"
);
transaction
.rollback()
.await
@ -78,6 +80,7 @@ pub async fn create_document(
)
.await
.map_err(server_error)?;
if let Some(latest_version) = latest_version {
info!(
"Document already exists at new location: `{sanitized_relative_path}` when trying to create it in vault `{vault_id}`, merging into existing document"
@ -85,7 +88,7 @@ pub async fn create_document(
return merge_with_stored_version(
&sanitized_relative_path,
&Vec::new(),
&latest_version.content.clone(),
latest_version,
vault_id,
user,

View file

@ -79,9 +79,12 @@ pub async fn update_text(
) -> Result<Json<DocumentUpdateResponse>, SyncServerError> {
let parent_document = get_parent_document(&state, &vault_id, request.parent_version_id).await?;
let parent_content = str::from_utf8(&parent_document.content)
.context("Parent document content is not valid UTF-8")
.map_err(client_error)?;
let edited_text = EditedText::from_diff(
str::from_utf8(&parent_document.content)
.expect("parent must be valid UTF-8 because it's a text document"),
parent_content,
request.content,
&*BuiltinTokenizer::Word,
)
@ -232,15 +235,20 @@ pub async fn merge_with_stored_version(
"Merging changes for document `{}` in vault `{vault_id}`",
latest_version.document_id
);
let parent_str = str::from_utf8(parent_document_content)
.context("Parent document content is not valid UTF-8")
.map_err(server_error)?;
let latest_str = str::from_utf8(&latest_version.content)
.context("Latest version content is not valid UTF-8")
.map_err(server_error)?;
let content_str = str::from_utf8(&content)
.context("New content is not valid UTF-8")
.map_err(server_error)?;
reconcile(
str::from_utf8(parent_document_content)
.expect("parent must be valid UTF-8 because it's not binary"),
&str::from_utf8(&latest_version.content)
.expect("latest_version must be valid UTF-8 because it's not binary")
.into(),
&str::from_utf8(&content)
.expect("content must be valid UTF-8 because it's not binary")
.into(),
parent_str,
&latest_str.into(),
&content_str.into(),
&*BuiltinTokenizer::Word,
)
.apply()

View file

@ -7,7 +7,7 @@ use axum::{
response::Response,
};
use futures::stream::StreamExt;
use log::{debug, info};
use log::{debug, info, warn};
use serde::Deserialize;
use crate::{
@ -101,24 +101,38 @@ async fn websocket(
let device_id = authed_handshake.handshake.device_id.clone();
let mut send_task = tokio::spawn(async move {
while let Ok(update) = broadcast_receiver.recv().await {
if Some(&device_id) == update.origin_device_id.as_ref() {
continue;
}
loop {
match broadcast_receiver.recv().await {
Ok(update) => {
if Some(&device_id) == update.origin_device_id.as_ref() {
continue;
}
let message = match update.message {
WebSocketServerMessage::CursorPositions(CursorPositionFromServer { clients }) => {
WebSocketServerMessage::CursorPositions(CursorPositionFromServer {
clients: clients
.into_iter()
.filter(|client| client.device_id != device_id)
.collect(),
})
let message = match update.message {
WebSocketServerMessage::CursorPositions(
CursorPositionFromServer { clients },
) => WebSocketServerMessage::CursorPositions(CursorPositionFromServer {
clients: clients
.into_iter()
.filter(|client| client.device_id != device_id)
.collect(),
}),
WebSocketServerMessage::VaultUpdate(_) => update.message,
};
send_update_over_websocket(&message, &mut sender).await?;
}
WebSocketServerMessage::VaultUpdate(_) => update.message,
};
send_update_over_websocket(&message, &mut sender).await?;
Err(tokio::sync::broadcast::error::RecvError::Lagged(n)) => {
warn!(
"WebSocket receiver for device {device_id} lagged by {n} messages, \
disconnecting for re-sync"
);
break;
}
Err(tokio::sync::broadcast::error::RecvError::Closed) => {
break;
}
}
}
Ok::<(), SyncServerError>(())