From aaa835ba8ba3318f46231af354fb58dd29cc91c7 Mon Sep 17 00:00:00 2001 From: Fons van der Plas Date: Sat, 24 Aug 2024 21:16:00 +0200 Subject: [PATCH] Fix out of order state update messages (#3010) --- frontend/components/Editor.js | 10 ++++++++++ src/webserver/Dynamic.jl | 12 ++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/frontend/components/Editor.js b/frontend/components/Editor.js index b6cc050877..72ead3a9db 100644 --- a/frontend/components/Editor.js +++ b/frontend/components/Editor.js @@ -788,6 +788,15 @@ all patches: ${JSON.stringify(patches, null, 1)} this.apply_notebook_patches = apply_notebook_patches // these are update message that are _not_ a response to a `send(*, *, {create_promise: true})` + this.last_update_counter = -1 + const check_update_counter = (new_val) => { + if (new_val <= this.last_update_counter) { + console.error("State update out of order", new_val, this.last_update_counter) + alert("Oopsie!! please refresh your browser and everything will be alright!") + } + this.last_update_counter = new_val + } + const on_update = (update, by_me) => { if (this.state.notebook.notebook_id === update.notebook_id) { const show_debugs = launch_params.binder_url != null @@ -795,6 +804,7 @@ all patches: ${JSON.stringify(patches, null, 1)} const message = update.message switch (update.type) { case "notebook_diff": + check_update_counter(message?.counter) let apply_promise = Promise.resolve() if (message?.response?.from_reset) { console.log("Trying to reset state after failure") diff --git a/src/webserver/Dynamic.jl b/src/webserver/Dynamic.jl index 59a3aaad64..32b28f783b 100644 --- a/src/webserver/Dynamic.jl +++ b/src/webserver/Dynamic.jl @@ -165,6 +165,10 @@ const current_state_for_clients = WeakKeyDict{ClientSession,Any}() const current_state_for_clients_lock = ReentrantLock() const update_counter_for_debugging = Ref(0) +const update_counter_for_clients_1 = WeakKeyDict{ClientSession,Any}() +const update_counter_for_clients_2 = WeakKeyDict{ClientSession,Any}() +const update_counter_for_clients_3 = WeakKeyDict{ClientSession,Any}() + """ Update the local state of all clients connected to this notebook. """ @@ -195,12 +199,12 @@ function send_notebook_changes!(🙋::ClientRequest; commentary::Any=nothing) end end end - end - for (client, msg) in outbox - putclientupdates!(client, msg) + for (client, msg) in outbox + putclientupdates!(client, msg) + end + try_event_call(🙋.session, FileEditEvent(🙋.notebook)) end - try_event_call(🙋.session, FileEditEvent(🙋.notebook)) end "Like `deepcopy`, but anything other than `Dict` gets a shallow (reference) copy."