Support passing an MFA for customizing shutdown (#1519)

This commit lets you customize Livebook shutdown to gracefully power
off. One use case is for Nerves-based devices that need to do more than
call `System.stop/0` to power off.

This doesn't change the `LIVEBOOK_SHUTDOWN_ENABLED` environment
variable. It still works the same.

The `:shutdown_enabled` configuration is now `:shutdown_callback`. Valid
values are `nil` or an MFA. An unset or `nil` callback hides the
shutdown button in the UI.
This commit is contained in:
Frank Hunleth 2022-11-10 12:09:01 -05:00 committed by GitHub
parent 31c119a633
commit 52e5273401
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 16 additions and 13 deletions

View file

@ -27,7 +27,7 @@ config :livebook,
force_ssl_host: nil,
learn_notebooks: [],
plugs: [],
shutdown_enabled: false,
shutdown_callback: nil,
storage: Livebook.Storage.Ets,
update_instructions_url: nil,
within_iframe: false

View file

@ -24,7 +24,7 @@ config :livebook, LivebookWeb.Endpoint,
]
config :livebook, :iframe_port, 4001
config :livebook, :shutdown_enabled, true
config :livebook, :shutdown_callback, {System, :stop, []}
# Feature flags
config :livebook, :feature_flags,

View file

@ -119,7 +119,7 @@ defmodule Livebook do
end
if Livebook.Config.boolean!("LIVEBOOK_SHUTDOWN_ENABLED", false) do
config :livebook, :shutdown_enabled, true
config :livebook, :shutdown_callback, {System, :stop, []}
end
if Livebook.Config.boolean!("LIVEBOOK_WITHIN_IFRAME", false) do

View file

@ -107,11 +107,11 @@ defmodule Livebook.Config do
end
@doc """
Returns whether the shutdown feature is enabled.
Returns an mfa if there's a way to shut down the system.
"""
@spec shutdown_enabled?() :: boolean()
def shutdown_enabled?() do
Application.fetch_env!(:livebook, :shutdown_enabled)
@spec shutdown_callback() :: mfa() | nil
def shutdown_callback() do
Application.fetch_env!(:livebook, :shutdown_callback)
end
@doc """

View file

@ -23,11 +23,14 @@ defmodule LivebookWeb.SidebarHook do
defp handle_info(_event, socket), do: {:cont, socket}
defp handle_event("shutdown", _params, socket) do
if Livebook.Config.shutdown_enabled?() do
System.stop()
{:halt, put_flash(socket, :info, "Livebook is shutting down. You can close this page.")}
else
socket
case Livebook.Config.shutdown_callback() do
{m, f, a} ->
apply(m, f, a)
{:halt, put_flash(socket, :info, "Livebook is shutting down. You can close this page.")}
_ ->
socket
end
end

View file

@ -113,7 +113,7 @@ defmodule LivebookWeb.LayoutHelpers do
<.hub_section socket={@socket} hubs={@saved_hubs} current_page={@current_page} />
</div>
<div class="flex flex-col">
<%= if Livebook.Config.shutdown_enabled?() do %>
<%= if Livebook.Config.shutdown_callback() do %>
<button
class="h-7 flex items-center text-gray-400 hover:text-white border-l-4 border-transparent hover:border-white"
aria-label="shutdown"