Reinitialize hooks on reconnection (#1018)

* Reinitialize cells on reconnection

* Send initial session data without additional roundtrip
This commit is contained in:
Jonatan Kłosko 2022-02-21 20:39:29 +01:00 committed by GitHub
parent 3bc219e5d8
commit 0386a032a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 21 deletions

View file

@ -164,6 +164,14 @@ const Cell = {
);
},
disconnected() {
// When disconnected, this client is no longer seen by the server
// and misses all collaborative changes. On reconnection we want
// to clean up and mount a fresh hook, which we force by ensuring
// the DOM id doesn't match
this.el.removeAttribute("id");
},
destroyed() {
this._unsubscribeFromNavigationEvents();
this._unsubscribeFromCellsEvents();

View file

@ -75,14 +75,6 @@ const Session = {
setFavicon(faviconForEvaluationStatus(this.props.globalStatus));
// Load initial data
this.pushEvent("session_init", {}, ({ clients }) => {
clients.forEach((client) => {
this.state.clientsMap[client.pid] = client;
});
});
// DOM events
this.handleDocumentKeyDown = (event) => {
@ -159,6 +151,12 @@ const Session = {
// Server events
this.handleEvent("session_init", ({ clients }) => {
clients.forEach((client) => {
this.state.clientsMap[client.pid] = client;
});
});
this.handleEvent("cell_inserted", ({ cell_id: cellId }) => {
handleCellInserted(this, cellId);
});
@ -235,6 +233,11 @@ const Session = {
}
},
disconnected() {
// Reinitialize on reconnection
this.el.removeAttribute("id");
},
destroyed() {
this._unsubscribeFromSessionEvents();

View file

@ -26,6 +26,20 @@ defmodule LivebookWeb.SessionLive do
Session.get_data(session_pid)
end
socket =
if connected?(socket) do
payload = %{
clients:
Enum.map(data.clients_map, fn {client_pid, user_id} ->
client_info(client_pid, data.users_map[user_id])
end)
}
push_event(socket, "session_init", payload)
else
socket
end
session = Session.get_by_pid(session_pid)
platform = platform_from_socket(socket)
@ -565,19 +579,6 @@ defmodule LivebookWeb.SessionLive do
end
@impl true
def handle_event("session_init", _params, socket) do
data = socket.private.data
payload = %{
clients:
Enum.map(data.clients_map, fn {client_pid, user_id} ->
client_info(client_pid, data.users_map[user_id])
end)
}
{:reply, payload, socket}
end
def handle_event("append_section", %{}, socket) do
idx = length(socket.private.data.notebook.sections)
Session.insert_section(socket.assigns.session.pid, idx)