Platform-aware Erlang distribution startup.
On iOS, distribution is started at BEAM launch via flags in mob_beam.m
(-name mob_demo@127.0.0.1), so nothing extra is needed here.
On Android, starting distribution at BEAM launch races with Android's hwui
thread pool initialization (~125ms window), corrupting an internal mutex and
causing a SIGABRT. The fix is to defer Node.start/2 until after the UI has
fully settled.
Additionally, mix mob.connect runs adb reverse tcp:4369 tcp:4369 to tunnel
Mac EPMD into the device. OTP's Node.start/2 would ordinarily spawn a local
epmd daemon that also tries to bind port 4369 — causing a port conflict and
crash. The fix: set start_epmd: false and wait for the ADB-tunnelled EPMD to
be reachable before calling Node.start/2. If the tunnel is not up within 10s
(standalone launch, no mix mob.connect), distribution is skipped gracefully.
Usage (in your app's start/0)
Mob.Dist.ensure_started(node: :"mob_demo@127.0.0.1", cookie: :mob_secret)Options:
:node— node name atom, e.g.:"mob_demo@127.0.0.1"(required on Android):cookie— cookie atom, e.g.:mob_secret(required on Android):delay— ms to wait before starting dist on Android (default: 3_000)
Summary
Functions
Ensure Erlang distribution is running for the current platform.
Stop Erlang distribution and shut down EPMD.
Functions
@spec ensure_started(keyword()) :: :ok
Ensure Erlang distribution is running for the current platform.
- iOS: no-op (dist already started via BEAM args in mob_beam.m).
- Android: spawns a process that sleeps for
:delayms then callsNode.start/2+Node.set_cookie/1. Pins the dist port to:dist_port(default 9100) sodev_connect.shknows which port to forward.
Options:
:node— node name atom (required on Android):cookie— cookie atom (required on Android):delay— ms to wait before starting dist (default: 3_000):dist_port— Erlang dist listen port (default: 9100)
@spec stop() :: :ok
Stop Erlang distribution and shut down EPMD.
Disconnects all connected nodes, stops the distribution listener, and terminates the local EPMD daemon if one was started by this node.
Intended for use after an OTA update session or when forming a Mob.Cluster
connection that should not persist. The app continues running normally after
calling stop/0 — only remote connectivity is removed.
Returns :ok whether or not distribution was running.
# OTA update session
Mob.Dist.ensure_started(node: :"my_app@127.0.0.1", cookie: session_cookie)
Node.connect(update_server_node)
# ... receive BEAMs ...
Mob.Dist.stop()
# Mob.Cluster — rotate cookie between sessions
Node.set_cookie(new_session_cookie) # no restart needed