erl_epmd(3)
π erl_epmd β bestie edition π
okay so you found the erl_epmd page, and honestly? iconic. this is the Erlang interface that talks to epmd, and i'm gonna walk you through every single thing on it, no skips, no skimming, periodt. β¨
π NAME π
erl_epmd β the Erlang interface towards epmd. that's it, that's the whole name section, shoutout to brevity. π
πΈ DESCRIPTION πΈ
so this module communicates with the EPMD daemon β go look at epmd for the deets on that guy.
and hiii, if you're the type of main character who wants to build your own epmd module instead of using the standard one? the universe has a doc for that: ERTS User's Guide: How to Implement an Alternative Node Discovery for Erlang Distribution. go read it, you got this. π¦
β¨ FUNCTIONS β¨
π« address_please(Name, Host, AddressFamily) -> Success | {error, term()}
lowkey the type signature here is giving:
address_please(Name, Host, AddressFamily) ->
Success | {error, term()}
when
Name :: string(),
Host :: string() | inet:ip_address(),
AddressFamily :: inet | inet6,
Port :: non_neg_integer(),
Version :: non_neg_integer(),
Success ::
{ok, inet:ip_address()} |
{ok, inet:ip_address(), Port, Version}.
this one gets called by the distribution module to resolve the Host into an IP address for a remote node. it's giving DNS but for Erlang, fr fr.
and here's the lil optimization moment: this function may also hand you back the port and version of that remote node. and if it does return port and version? then port_please/3 won't even get called. efficient queen. π
Name::string()Host::string()|inet:ip_address()AddressFamily::inet|inet6Port::non_neg_integer()Version::non_neg_integer()Success::{ok, inet:ip_address()}|{ok, inet:ip_address(), Port, Version}
π« listen_port_please(Name, Host) -> {ok, Port}
listen_port_please(Name, Host) -> {ok, Port}
when
Name :: atom() | string(),
Host ::
atom() |
string() |
inet:ip_address(),
Port :: non_neg_integer().
called by the distribution module to figure out which port the local node should listen to when it's accepting brand new distribution requests. basically "babe, which door are we answering?" πͺβ¨
Name::atom()|string()Host::atom()|string()|inet:ip_address()Port::non_neg_integer()
π« names(Host) -> {ok, [{Name, Port}]} | {error, Reason}
names(Host) -> {ok, [{Name, Port}]} | {error, Reason}
when
Host :: atom() | string() | inet:ip_address(),
Name :: string(),
Port :: non_neg_integer(),
Reason :: address | file:posix().
this one is called by net_adm:names/0. Host defaults to the localhost, cute.
it returns the names and associated port numbers of all the Erlang nodes that epmd registered on the specified host. and if epmd is literally not operational? you get {error, address}. not a vibe, but you'll know. π
example, bestie:
(arne@dunn)1> erl_epmd:names(localhost).
{ok,[{"arne",40262}]}
see? arne is out here on port 40262. slay.
Host::atom()|string()|inet:ip_address()Name::string()Port::non_neg_integer()Reason::address|file:posix()
π« port_please(Name, Host, Timeout) -> {port, Port, Version} | noport | closed | {error, term()}
port_please(Name, Host, Timeout) ->
{port, Port, Version} |
noport | closed |
{error, term()}
when
Name :: atom() | string(),
Host :: atom() | string() | inet:ip_address(),
Timeout :: non_neg_integer() | infinity,
Port :: non_neg_integer(),
Version :: non_neg_integer().
this bad boy requests the distribution port for the given node of an EPMD instance. and along with the port, it hands you a distribution protocol version β which has been 5 ever since Erlang/OTP R6. yes bestie, 5, that number has not moved in a MINUTE. π°οΈ
Name::atom()|string()Host::atom()|string()|inet:ip_address()Timeout::non_neg_integer()|infinityPort::non_neg_integer()Version::non_neg_integer()
π« register_node(Name, Port, Driver) -> Result
register_node(Name, Port, Driver) -> Result
when
Name :: string(),
Port :: non_neg_integer(),
Driver :: inet_tcp | inet6_tcp | inet | inet6,
Creation :: non_neg_integer() | -1,
Result ::
{ok, Creation} |
{error, already_registered} |
term().
so this one registers the node with epmd and tells epmd exactly what port the current node is gonna use. it gives you back a creation number, and that number gets incremented on every single register β the whole point being to help tell apart a new node instance that's connecting to epmd with the same old name. messy name collisions? handled. π
and here's the glow-up: once the node has successfully registered with epmd, it will automatically attempt to reconnect to the daemon if the connection breaks. self-healing behavior, we love to see it. π«Ά
Name::string()Port::non_neg_integer()Driver::inet_tcp|inet6_tcp|inet|inet6Creation::non_neg_integer()|-1Result::{ok, Creation}|{error, already_registered}|term()
π« start_link() -> {ok, pid()} | ignore | {error, term()}
start_link() -> {ok, pid()} | ignore | {error, term()}.
this function gets invoked because this module is added as a child of the erl_distribution supervisor. it's giving "i'm part of the family now." π
okay bestie that's the whole page, every option, every type, every example, all present and accounted for, no cap. π
mwah, this doc came from Ericsson AB, part of kernel 11.0.3, and it's the erl_epmd(3) page. go forth and distribute, you gorgeous node. πβ¨π¦
π¦ where this page comes from
- ubuntu stonking: erlang-doc 1:29.0.6+dfsg-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms