CliSubprocessCore.Channel is the framed-IO layer above CliSubprocessCore.RawSession.
Use it when you need a long-lived subprocess handle with stable mailbox
delivery, but you do not want provider-aware parsing from CliSubprocessCore.Session.
When To Use A Channel
Use Channel when you need:
- long-lived stdin/stdout/stderr ownership
- stable tagged mailbox delivery without carrying a raw transport ref around
- the same local-versus-SSH execution surface used by the lower transport APIs
If you only need one-shot execution, use CliSubprocessCore.Command.run/1,2 or
ExecutionPlane.Process.Transport.run/2. If you want provider parsing and
normalized CliSubprocessCore.Event values, use CliSubprocessCore.Session.
Start A Channel
ref = make_ref()
{:ok, channel, info} =
CliSubprocessCore.Channel.start_channel(
command: "sh",
args: ["-c", "cat"],
subscriber: {self(), ref},
stdout_mode: :raw,
stdin_mode: :raw
)
IO.inspect(info.delivery)
:ok = CliSubprocessCore.Channel.send_input(channel, "alpha")
:ok = CliSubprocessCore.Channel.close_input(channel)
receive do
message ->
case CliSubprocessCore.Channel.extract_event(message, ref) do
{:ok, {:data, chunk}} -> IO.inspect(chunk)
{:ok, {:exit, exit}} -> IO.inspect(exit.code)
:error -> :ignore
end
endstart_channel/1 returns the pid plus the initial info snapshot.
start_link_channel/1 returns the same snapshot while keeping the channel
linked to the caller.
Mailbox Contract
Legacy subscribers receive:
{:channel_message, line}
{:channel_data, chunk}
{:channel_stderr, chunk}
{:channel_exit, exit}
{:channel_error, reason}Tagged subscribers receive:
{:cli_subprocess_core_channel, ref, {:message, line}}
{:cli_subprocess_core_channel, ref, {:data, chunk}}
{:cli_subprocess_core_channel, ref, {:stderr, chunk}}
{:cli_subprocess_core_channel, ref, {:exit, exit}}
{:cli_subprocess_core_channel, ref, {:error, reason}}Use CliSubprocessCore.Channel.extract_event/2 instead of matching on the
outer event atom directly.
Delivery And Metadata
CliSubprocessCore.Channel.info/1 returns:
deliverymetadata for the effective mailbox contract- the normalized invocation
- subscriber count
- the underlying raw-session info
- the transport snapshot, including
surface_kind, stderr tail, and adapter metadata
CliSubprocessCore.Channel.delivery_info/1 is the shortest path to the stable
tagged-delivery contract.
SSH Surfaces
Channels use the same generic execution-surface options as the transport layer. For an SSH execution surface:
{:ok, channel, _info} =
CliSubprocessCore.Channel.start_channel(
command: "sh",
args: ["-c", "cat"],
subscriber: {self(), make_ref()},
stdout_mode: :raw,
stdin_mode: :raw,
execution_surface: [
surface_kind: :ssh_exec,
transport_options: [
destination: "channel.test.example",
ssh_user: "deploy",
port: 22
]
]
)The core still resolves the SSH adapter internally. Callers stay on one
canonical execution_surface.