erldistpy/erldistpy/__init__.py
russell@unturf.com ac4636e00c
phase 5: Node.call() gen_server protocol
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.
2026-06-16 11:33:28 -04:00

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",
]