Node wraps EPMD lookup + handshake + Channel into a single client
object. Constructor eagerly opens the dist connection; call() runs the
synchronous $gen_call protocol against a registered name on the peer:
caller -> {'$gen_call', {FromPid, Ref}, Request} (REG_SEND)
server -> {Ref, Reply} (SEND)
Synthesized FromPid and a Node-lifetime Ref counter route replies back
to us; mismatched Ref or unexpected control op raises CallProtocolError.
Reply timeout raises CallTimeout (also covers Erlang's silent-drop case
when the registered name doesn't exist).
Tests against an erl peer running a $gen_call-aware loop:
- {ping, X} -> {pong, X}
- {add, A, B} -> {ok, A + B}
- five sequential calls with monotonically increasing Refs
- server error response surfaces as Python tuple
- slow responder triggers CallTimeout
- unknown registered name surfaces as CallTimeout
- ref uniqueness across 100 synthesized refs
111 tests green across 10 consecutive runs, lint clean.
37 lines
807 B
Python
37 lines
807 B
Python
"""erldistpy — native Python client for our Erlang distribution protocol."""
|
|
|
|
__version__ = "0.0.1"
|
|
|
|
from erldistpy.channel import Channel, ChannelError, IncomingMessage
|
|
from erldistpy.epmd import EpmdError, EpmdInfo, lookup
|
|
from erldistpy.etf import (
|
|
Atom,
|
|
Pid,
|
|
Reference,
|
|
decode,
|
|
encode,
|
|
)
|
|
from erldistpy.handshake import HandshakeError, HandshakeResult, handshake
|
|
from erldistpy.node import CallProtocolError, CallTimeout, Node, NodeError
|
|
|
|
__all__ = [
|
|
"Atom",
|
|
"CallProtocolError",
|
|
"CallTimeout",
|
|
"Channel",
|
|
"ChannelError",
|
|
"EpmdError",
|
|
"EpmdInfo",
|
|
"HandshakeError",
|
|
"HandshakeResult",
|
|
"IncomingMessage",
|
|
"Node",
|
|
"NodeError",
|
|
"Pid",
|
|
"Reference",
|
|
"__version__",
|
|
"decode",
|
|
"encode",
|
|
"handshake",
|
|
"lookup",
|
|
]
|