Packages
livebook
0.18.4
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/epmd.ex
defmodule Livebook.EPMD do
# A custom EPMD module used to bypass the epmd OS daemon on Livebook.
#
# We also use it for the Fly runtime, such that we connect to the
# remote node via a local proxy port.
# From Erlang/OTP 23+
@epmd_dist_version 6
@doc """
Gets a random child node name.
"""
def random_child_node() do
String.to_atom(Livebook.EPMD.NodePool.get_name())
end
@doc """
Updates the port information for the given node.
"""
def update_child_node(node, port) do
Livebook.EPMD.NodePool.update_name(Atom.to_string(node), port)
end
@doc """
Returns the Livebook distribution port, if Livebook.EPMD is running, otherwise 0.
"""
def dist_port do
:persistent_term.get(:livebook_dist_port, 0)
end
# Custom EPMD callbacks
# Custom callback to register our current node port.
def register_node(name, port), do: register_node(name, port, :inet)
def register_node(name, port, family) do
:persistent_term.put(:livebook_dist_port, port)
case :erl_epmd.register_node(name, port, family) do
{:ok, creation} -> {:ok, creation}
{:error, :already_registered} -> {:error, :already_registered}
# If registration fails because EPMD is not running, we ignore
# that, because we do not rely on EPMD
_ -> {:ok, -1}
end
end
# Custom callback that accesses the parent information.
def port_please(name, host), do: port_please(name, host, :infinity)
def port_please(~c"remote_runtime_" ++ port, _host, _timeout) do
# The node name includes the local port proxied to a remote machine
port = List.to_integer(port)
{:port, port, @epmd_dist_version}
end
def port_please(name, host, timeout) do
:erl_epmd.port_please(name, host, timeout)
end
# Custom callback for resolving remote runtime node domain, such as
# Fly .internal, to loopback, because we communicate via a local
# proxied port
def address_please(~c"remote_runtime_" ++ _, _host, address_family) do
case address_family do
:inet -> {:ok, {127, 0, 0, 1}}
:inet6 -> {:ok, {0, 0, 0, 0, 0, 0, 0, 1}}
end
end
def address_please(name, host, address_family) do
:erl_epmd.address_please(name, host, address_family)
end
# Default EPMD callbacks
defdelegate start_link(), to: :erl_epmd
defdelegate listen_port_please(name, host), to: :erl_epmd
defdelegate names(host_name), to: :erl_epmd
end