Snodo.Transport.Stdio (snodo v0.2.0)

Copy Markdown View Source

Concurrent newline-delimited JSON-RPC transport.

A small coordinator owns framing and serializes complete stdout writes. Work is admitted through the optional, transport-neutral Snodo.Server.Executor, so the coordinator never awaits a handler and execution policy is reusable by other transports.

:write_timeout is a positive millisecond limit, defaulting to 5,000. A single linked, monitored helper performs each write while the coordinator waits boundedly; there is no writer queue. Cancellation and EOF handling can wait up to this limit during a blocked write. A timeout or output error is terminal: the transport cancels its work and closes subscriptions, without attempting further writes. A timed-out device may already have accepted some bytes, so the transport never retries. Supplied I/O devices are never stopped or killed.

:max_line_bytes limits one input message, defaulting to 2,000,000 bytes to match the HTTP listener's :max_body_bytes. A longer line is answered with -32600 and a null id without being decoded, and the next line is served normally. The VM's I/O server buffers each line in full before returning it, so this bounds decoding and dispatch, not that read buffer.

Summary

Functions

Returns a specification to start this module under a supervisor.

Runs the stdio transport until EOF and all admitted requests finish.

Types

state()

@type state() :: %{
  runtime: Snodo.Server.Runtime.t(),
  input: IO.device(),
  output: IO.device(),
  writer: {IO.device(), pos_integer()},
  executor: pid(),
  executor_monitor: reference() | nil,
  serve_owner_monitor: reference() | nil,
  owns_executor?: boolean(),
  request_timeout: Snodo.Server.Executor.execution_timeout() | :default,
  reader: pid() | nil,
  connection_ref: reference(),
  executions_by_id: map(),
  executions_by_ref: map(),
  subscriptions_by_id: map(),
  subscriptions_by_worker: map(),
  max_subscriptions: pos_integer(),
  max_line_bytes: pos_integer(),
  eof?: boolean()
}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

serve(runtime, opts \\ [])

@spec serve(Snodo.Server.Runtime.t(), keyword()) :: :ok | {:error, term()}

Runs the stdio transport until EOF and all admitted requests finish.