Packages
livebook
0.6.1
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
@moduledoc false
# 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, Utils}
@doc """
Spawns a new `Session` process with the given options.
Makes the session globally visible within the session tracker.
"""
@spec create_session(keyword()) :: {:ok, Session.t()} | {:error, any()}
def create_session(opts \\ []) do
id = Utils.random_node_aware_id()
opts = Keyword.put(opts, :id, id)
case DynamicSupervisor.start_child(Livebook.SessionSupervisor, {Session, opts}) do
{:ok, pid} ->
session = Session.get_by_pid(pid)
case Livebook.Tracker.track_session(session) do
:ok ->
{:ok, session}
{:error, reason} ->
Session.close(pid)
{:error, reason}
end
{: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
def fetch_session(id) do
case Livebook.Tracker.fetch_session(id) do
{:ok, session} ->
{:ok, session}
:error ->
# 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
with {:ok, other_node} when other_node != node() <- Utils.node_from_node_aware_id(id),
{:ok, session} <- :rpc.call(other_node, Livebook.Tracker, :fetch_session, [id]) do
{:ok, session}
else
_ -> :error
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