Skip to content

Commit 033f31f

Browse files
committed
Docs: Rethink approach to file sync.
1 parent 50c5446 commit 033f31f

File tree

2 files changed

+25
-35
lines changed

2 files changed

+25
-35
lines changed

server/src/processing.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,10 @@ pub struct CodeMirrorDocBlockDelete {
187187
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TS)]
188188
#[ts(export, optional_fields)]
189189
pub struct StringDiff {
190-
/// The index into the previous `CodeMirrorDocBlockVec` of the start of the
191-
/// change.
190+
/// The index of the start of the change, in UTF-16 code units.
192191
pub from: usize,
193192
/// The index of the end of the change; defined for deletions and
194-
/// replacements. See the
193+
/// replacements, in UTF-16 code units. See the
195194
/// [skip serializing field docs](https://serde.rs/attr-skip-serializing.html);
196195
/// this must be excluded from the JSON output if it's `None` to avoid
197196
/// CodeMirror errors.

server/src/translation.rs

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,12 @@ pub fn create_translation_queues(
297297
) -> Result<CreatedTranslationQueues, CreateTranslationQueuesError> {
298298
// There are three cases for this `connection_id`:
299299
//
300-
// 1. It hasn't been used before. In this case, create the appropriate
301-
// queues and start websocket and processing tasks.
302-
// 2. It's in use, but was disconnected. In this case, re-use the queues
303-
// and start the websocket task; the processing task is still running.
304-
// 3. It's in use by another IDE. This is an error, but I don't have a way
305-
// to detect it yet.
300+
// 1. It hasn't been used before. In this case, create the appropriate
301+
// queues and start websocket and processing tasks.
302+
// 2. It's in use, but was disconnected. In this case, re-use the queues and
303+
// start the websocket task; the processing task is still running.
304+
// 3. It's in use by another IDE. This is an error, but I don't have a way
305+
// to detect it yet.
306306
//
307307
// Check case 3.
308308
if app_state
@@ -421,34 +421,25 @@ pub async fn translation_task(
421421
// (since it would have contained Markdown).
422422
let mut code_mirror_doc_blocks = Some(Vec::new());
423423
let prefix_str = "/".to_string() + &prefix.join("/");
424-
// To send a diff from Server to Client or vice versa, we need to
425-
// ensure they are in sync:
424+
// To support sending diffs, we must provide a way to determine if
425+
// the sender and receiver have the same file contents before
426+
// applying a diff. File contents can become unsynced due to:
426427
//
427-
// 1. IDE update -> Server -> Client or Client update -> Server ->
428-
// IDE: the Server and Client sync is pending. Client response
429-
// -> Server -> IDE or IDE response -> Server -> Client: the
430-
// Server and Client are synced.
431-
// 2. IDE current file -> Server -> Client or Client current file
432-
// -> Server -> IDE: Out of sync.
428+
// 1. A dropped/lost message between the IDE and Client.
429+
// 2. Edits to file contents in two locations before updates from
430+
// one location (the Client, for example) propagate to the other
431+
// location (the IDE).
433432
//
434-
// It's only safe to send a diff when the most recent sync is
435-
// achieved. So, we need to track the ID of the most recent IDE ->
436-
// Client update or Client -> IDE update, if one is in flight. When
437-
// complete, mark the connection as synchronized. Since all IDs are
438-
// unique, we can use a single variable to store the ID.
439-
//
440-
// Currently, when the Client sends an update, mark the connection
441-
// as out of sync, since the update contains not HTML in the doc
442-
// blocks, but Markdown. When Turndown is moved from JavaScript to
443-
// Rust, this can be changed, since both sides will have HTML in the
444-
// doc blocks.
445-
//
446-
// Another approach: use revision numbers. Both the IDE and Client
447-
// start with the same revision number. When either makes an edit,
448-
// it sends a new revision number along with a diff. If the receiver
449-
// doesn't have the previous version, it returns a result of error,
450-
// which prompts the sender to re-send with the full text instead of
451-
// a diff.
433+
// Therefore, assign each file a version number. All files are sent
434+
// with a unique, randomly-generated version number which define the
435+
// file's version after this update is applied. Diffs also include
436+
// the version number of the file before applying the diff; the
437+
// receiver's current version number must match with the sender's
438+
// pre-diff version number in order to apply the diff. When the
439+
// versions don't match, the IDE must send a full text file to the
440+
// Server and Client to re-sync. When a file is first loaded, its
441+
// version number is None, signaling that the sender must always
442+
// provide the full text, not a diff.
452443
let mut sync_state = SyncState::OutOfSync;
453444
loop {
454445
select! {

0 commit comments

Comments
 (0)