mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-04 03:54:24 +08:00
Suggest restarting runtime on Mix.install error and add restart shortcut (#418)
* Suggest restarting runtime on Mix.install error and add restart shortcut * Apply review comments
This commit is contained in:
parent
6515629156
commit
20ff5c95b8
12 changed files with 81 additions and 4 deletions
|
@ -301,6 +301,8 @@ function handleDocumentKeyDown(hook, event) {
|
|||
showBin(hook);
|
||||
} else if (keyBuffer.tryMatch(["e", "x"])) {
|
||||
cancelFocusedCellEvaluation(hook);
|
||||
} else if (keyBuffer.tryMatch(["0", "0"])) {
|
||||
restartRuntime(hook);
|
||||
} else if (keyBuffer.tryMatch(["?"])) {
|
||||
showShortcuts(hook);
|
||||
} else if (keyBuffer.tryMatch(["i"])) {
|
||||
|
@ -594,6 +596,10 @@ function cancelFocusedCellEvaluation(hook) {
|
|||
}
|
||||
}
|
||||
|
||||
function restartRuntime(hook) {
|
||||
hook.pushEvent("restart_runtime", {});
|
||||
}
|
||||
|
||||
function showShortcuts(hook) {
|
||||
hook.pushEvent("show_shortcuts", {});
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ defmodule Livebook.Evaluator.DefaultFormatter do
|
|||
|
||||
def format_response({:error, kind, error, stacktrace}) do
|
||||
formatted = Exception.format(kind, error, stacktrace)
|
||||
{:error, formatted}
|
||||
{:error, formatted, error_type(error)}
|
||||
end
|
||||
|
||||
@compile {:no_warn_undefined, {Kino.Render, :to_livebook, 1}}
|
||||
|
@ -80,4 +80,17 @@ defmodule Livebook.Evaluator.DefaultFormatter do
|
|||
reset: :reset
|
||||
]
|
||||
end
|
||||
|
||||
defp error_type(error) do
|
||||
cond do
|
||||
mix_install_vm_error?(error) -> :runtime_restart_required
|
||||
true -> :other
|
||||
end
|
||||
end
|
||||
|
||||
defp mix_install_vm_error?(exception) do
|
||||
is_struct(exception, Mix.Error) and
|
||||
Exception.message(exception) =~
|
||||
"Mix.install/2 can only be called with the same dependencies"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,7 +38,7 @@ defmodule Livebook.Notebook.Cell.Elixir do
|
|||
# Interactive data table
|
||||
| {:table_dynamic, widget_process :: pid()}
|
||||
# Internal output format for errors
|
||||
| {:error, message :: binary()}
|
||||
| {:error, message :: binary(), type :: :other | :runtime_restart_required}
|
||||
|
||||
@doc """
|
||||
Returns an empty cell.
|
||||
|
|
|
@ -106,4 +106,10 @@ defprotocol Livebook.Runtime do
|
|||
container_ref,
|
||||
evaluation_ref
|
||||
)
|
||||
|
||||
@doc """
|
||||
Synchronously starts a runtime of the same type with the same parameters.
|
||||
"""
|
||||
@spec duplicate(Runtime.t()) :: {:ok, Runtime.t()} | {:error, String.t()}
|
||||
def duplicate(runtime)
|
||||
end
|
||||
|
|
|
@ -89,4 +89,8 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.Attached do
|
|||
evaluation_ref
|
||||
)
|
||||
end
|
||||
|
||||
def duplicate(_runtime) do
|
||||
{:error, "attached runtime is connected to a specific VM and cannot be duplicated"}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -113,4 +113,8 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.ElixirStandalone do
|
|||
evaluation_ref
|
||||
)
|
||||
end
|
||||
|
||||
def duplicate(_runtime) do
|
||||
Livebook.Runtime.ElixirStandalone.init()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -95,4 +95,9 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.Embedded do
|
|||
evaluation_ref
|
||||
)
|
||||
end
|
||||
|
||||
def duplicate(_runtime) do
|
||||
{:error,
|
||||
"embedded runtime is connected to the Livebook application VM and cannot be duplicated"}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -166,4 +166,8 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.MixStandalone do
|
|||
evaluation_ref
|
||||
)
|
||||
end
|
||||
|
||||
def duplicate(runtime) do
|
||||
Livebook.Runtime.MixStandalone.init(runtime.project_path)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -566,6 +566,24 @@ defmodule LivebookWeb.SessionLive do
|
|||
push_patch(socket, to: Routes.session_path(socket, :bin, socket.assigns.session_id))}
|
||||
end
|
||||
|
||||
def handle_event("restart_runtime", %{}, socket) do
|
||||
socket =
|
||||
if runtime = socket.private.data.runtime do
|
||||
case Runtime.duplicate(runtime) do
|
||||
{:ok, new_runtime} ->
|
||||
Session.connect_runtime(socket.assigns.session_id, new_runtime)
|
||||
socket
|
||||
|
||||
{:error, message} ->
|
||||
put_flash(socket, :error, "Failed to setup runtime - #{message}")
|
||||
end
|
||||
else
|
||||
socket
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("completion_request", %{"hint" => hint, "cell_id" => cell_id}, socket) do
|
||||
data = socket.private.data
|
||||
|
||||
|
|
|
@ -337,7 +337,22 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
)
|
||||
end
|
||||
|
||||
defp render_output(_socket, {:error, formatted}, _id) do
|
||||
defp render_output(_socket, {:error, formatted, :runtime_restart_required}, _id) do
|
||||
assigns = %{formatted: formatted}
|
||||
|
||||
~L"""
|
||||
<div class="flex flex-col space-y-4">
|
||||
<%= render_error_message_output(@formatted) %>
|
||||
<div>
|
||||
<button class="button button-gray" phx-click="restart_runtime">
|
||||
Restart runtime
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp render_output(_socket, {:error, formatted, _type}, _id) do
|
||||
render_error_message_output(formatted)
|
||||
end
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ defmodule LivebookWeb.SessionLive.ShortcutsComponent do
|
|||
%{seq: ["s", "s"], desc: "Toggle sections panel"},
|
||||
%{seq: ["s", "u"], desc: "Toggle users panel"},
|
||||
%{seq: ["s", "r"], desc: "Show runtime settings"},
|
||||
%{seq: ["s", "b"], desc: "Show bin"}
|
||||
%{seq: ["s", "b"], desc: "Show bin"},
|
||||
%{seq: ["0", "0"], desc: "Restart current runtime"}
|
||||
],
|
||||
universal: [
|
||||
%{seq: ["ctrl", "s"], seq_mac: ["⌘", "s"], press_all: true, desc: "Save notebook"}
|
||||
|
|
|
@ -15,5 +15,6 @@ defmodule Livebook.Runtime.NoopRuntime do
|
|||
def forget_evaluation(_, _, _), do: :ok
|
||||
def drop_container(_, _), do: :ok
|
||||
def request_completion_items(_, _, _, _, _, _), do: :ok
|
||||
def duplicate(_), do: {:ok, Livebook.Runtime.NoopRuntime.new()}
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue