Testing concurrent remote updates (wip)

mrazator/delta-based-sync
Marcel Mraz 2 months ago
parent 7e0f5b6369
commit cdd7f6158b
No known key found for this signature in database
GPG Key ID: 4EBD6E62DC830CD2

@ -3878,6 +3878,7 @@ class App extends React.Component<AppProps, AppState> {
// flush all incoming updates immediately, so that they couldn't be batched with other updates, having different `storeAction`
flushSync(() => {
const { elements, appState, collaborators, storeAction } = sceneData;
const nextElements = elements
? syncInvalidIndices(elements)
: undefined;
@ -3892,8 +3893,8 @@ class App extends React.Component<AppProps, AppState> {
const nextCommittedElements = elements
? this.store.filterUncomittedElements(
this.scene.getElementsMapIncludingDeleted(), // Only used to detect uncomitted local elements
arrayToMap(nextElements ?? []), // We expect all (already reconciled) elements
this.scene.getElementsMapIncludingDeleted(), // only used to detect uncomitted local elements
arrayToMap(nextElements ?? []), // we expect all (already reconciled) elements
)
: prevCommittedElements;

@ -224,6 +224,8 @@ export class Store {
const increment = new EphemeralStoreIncrement(change);
// Notify listeners with the increment
// CFDO: consider having this async instead, possibly should also happen after the component updates;
// or get rid of filtering local in progress elements, switch to unidirectional store flow and keep it synchronous
this.onStoreIncrementEmitter.trigger(increment);
return nextSnapshot;

@ -17,6 +17,7 @@ import type { ExcalidrawElement, SceneElementsMap } from "../element/types";
import type { CLIENT_MESSAGE_RAW, SERVER_DELTA, CHANGE } from "./protocol";
import { debounce } from "../utils";
import { randomId } from "../random";
import { orderByFractionalIndex } from "../fractionalIndex";
class SocketMessage implements CLIENT_MESSAGE_RAW {
constructor(
@ -388,13 +389,18 @@ export class SyncClient {
!existingElement || // new element
existingElement.version < relayedElement.version // updated element
) {
// CFDO: in theory could make the yet unsynced element (due to a bug) to move to the top
nextElements.set(id, relayedElement);
this.relayedElementsVersionsCache.set(id, relayedElement.version);
}
}
const orderedElements = orderByFractionalIndex(
Array.from(nextElements.values()),
);
this.api.updateScene({
elements: Array.from(nextElements.values()),
elements: orderedElements,
storeAction: StoreAction.UPDATE,
});
} catch (e) {
@ -468,9 +474,13 @@ export class SyncClient {
prevSnapshot = this.api.store.snapshot;
}
const orderedElements = orderByFractionalIndex(
Array.from(nextElements.values()),
);
// CFDO: might need to restore first due to potentially stale delta versions
this.api.updateScene({
elements: Array.from(nextElements.values()),
elements: orderedElements,
// even though the snapshot should be up-to-date already,
// still some more updates might be triggered,
// i.e. as a result from syncing invalid indices

Loading…
Cancel
Save