Packages
livebook
0.17.2
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook/sessions.ex
defmodule Livebook.Sessions do
# This module is responsible for starting and discovering sessions.
#
# Every session has a server process and is described by a `%Session{}`
# info struct. Information about all sessions in the cluster is
# propagated using `Livebook.Tracker`, which serves as an ephemeral
# distributed database for the `%Session{}` structs.
alias Livebook.Session
@doc """
Spawns a new `Session` process with the given options.
"""
@spec create_session(keyword()) :: {:ok, Session.t()} | {:error, any()}
def create_session(opts \\ []) do
id = Livebook.Utils.random_node_aware_id()
opts = Keyword.put(opts, :id, id)
case DynamicSupervisor.start_child(Livebook.SessionSupervisor, {Session, opts}) do
{:ok, _pid, session} ->
{:ok, session}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Returns all the running sessions.
"""
@spec list_sessions() :: list(Session.t())
def list_sessions() do
Livebook.Tracker.list_sessions()
end
@doc """
Returns tracked session with the given id.
"""
@spec fetch_session(Session.id()) ::
{:ok, Session.t()} | {:error, :not_found | :different_boot_id}
def fetch_session(id) do
case Livebook.Tracker.fetch_session(id) do
{:ok, session} ->
{:ok, session}
:error ->
boot_id = Livebook.Config.random_boot_id()
case Livebook.Utils.node_from_node_aware_id(id) do
# The local tracker server doesn't know about this session,
# but it may not have propagated yet, so we extract the session
# node from id and ask the corresponding tracker directly
{:ok, other_node, _other_boot_id} when other_node != node() ->
case :rpc.call(other_node, Livebook.Tracker, :fetch_session, [id]) do
{:ok, session} -> {:ok, session}
_ -> {:error, :not_found}
end
{:ok, other_node, other_boot_id}
when other_node == node() and other_boot_id != boot_id ->
{:error, :different_boot_id}
_ ->
{:error, :not_found}
end
end
end
@doc """
Updates the given session info across the cluster.
"""
@spec update_session(Session.t()) :: :ok | {:error, any()}
def update_session(session) do
Livebook.Tracker.update_session(session)
end
@doc """
Subscribes to update in sessions list.
## Messages
* `{:session_created, session}`
* `{:session_updated, session}`
* `{:session_closed, session}`
"""
@spec subscribe() :: :ok | {:error, term()}
def subscribe() do
Phoenix.PubSub.subscribe(Livebook.PubSub, "tracker_sessions")
end
end