NAME
Remote::Perl::Protocol - wire protocol constants and codec (internal part of Remote::Perl)
DESCRIPTION
This module defines constants, encoding helpers, and an incremental parser for the Remote::Perl binary wire protocol.
INTERNAL
Not public API. This is an internal module used by Remote::Perl; its interface may change without notice.
FRAMING
Every message consists of:
- 1. Message type (uint8)
- 2. Stream ID (uint8)
- 3. Body length in bytes (uint32, big-endian)
- 4. Body (0 or more bytes)
Total header: 6 bytes. Body may be empty.
STREAMS
Streams multiplex logical channels over the single pipe pair. Predefined stream IDs:
ID Name Direction Purpose
-- ---- --------- -------
0 control bidirectional Connection lifecycle, errors
1 stdin local->remote Data forwarded to the remote script's STDIN
2 stdout remote->local Remote script's STDOUT
3 stderr remote->local Remote script's STDERR
4+ modules bidirectional One ephemeral stream per module transfer
Module transfer streams are opened by the remote side (MOD_REQ) and closed after the module source has been delivered (or refused) by the local side.
FLOW CONTROL
Each (sender, stream) pair has a credit counter. The sender may not transmit more body bytes than it currently holds in credit for that stream. Credits are granted by the receiver with CREDIT messages as it consumes data.
Initial credits (bytes) per stream are exchanged in the HELLO handshake. Default: 65536 bytes per stream, configurable via --window-size / the window_size constructor argument.
A sender that exhausts its credit must block until more is granted. A receiver must grant credits promptly to avoid deadlock.
Both sides use a select-based single-threaded event loop. This naturally handles concurrent and recursive module requests (multiple MOD_REQ streams in flight at once) without threads or external concurrency dependencies.
MESSAGE TYPES
Value Name Direction Body
----- ---- --------- ----
0x00 HELLO local->remote Protocol version (uint8) + initial credits (uint32)
0x01 READY remote->local Acknowledgement of HELLO; remote client active
0x10 RUN local->remote argc (uint32) + [len (uint32) + arg bytes]... + source bytes
0x20 DATA any direction Payload for the named stream
0x21 EOF any direction Stream has no more data (half-close)
0x30 CREDIT any direction uint32 BE: additional bytes granted to sender on this stream
0x40 MOD_REQ remote->local Module filename (e.g. Foo/Bar.pm); stream ID in header
0x41 MOD_MISSING local->remote Module not found; body empty
0x50 RETURN remote->local Exit code (uint8) + optional message bytes
0x60 SIGNAL local->remote Signal name bytes (e.g. "INT", "TERM")
0x61 SIGNAL_ACK remote->local Echoes signal name; signal delivered to executor
0xE0 ERROR any direction Error message bytes; sender will send no more
0xF0 BYE any direction Clean shutdown; no more messages expected
CONNECTION SEQUENCE
local remote
|--- HELLO --------------------->| bootstrap code already eval'd
|<-- READY ----------------------|
|--- RUN (stream 0) ------------>| send script source
|<-- DATA (stdout, stream 2) ----| output as produced
|--- DATA (stdin, stream 1) ---->| forwarded on demand
|--- CREDIT (stream 2) --------->| grant more stdout credit
|<-- MOD_REQ (stream 4) ---------| require 'Foo/Bar.pm'
|--- DATA (stream 4) ----------->| module source bytes
|--- EOF (stream 4) ------------>| module transfer complete
|<-- RETURN (stream 0) ----------| script finished
|--- BYE ----------------------->|
|<-- BYE ------------------------|