Tcp

Tcp :: # (opaque)

Connect to TCP servers and exchange buffered byte streams.

connect! : Str, U16 => Try(
    Stream,
    [
        AddrInUse,
        AddrNotAvailable,
        ConnectionRefused,
        Interrupted,
        PermissionDenied,
        TimedOut,
        Unrecognized(
            Str,
        ),
        Unsupported,
    ],
)

Opens a TCP connection to a remote host.

# Connect to localhost:8080
stream = Tcp.connect!("localhost", 8080)?

Valid hostnames look like 127.0.0.1, ::1, localhost, or roc-lang.org.

close! : Stream => {  }

Close a TCP stream immediately by shutting the socket down in both directions. The underlying resources are freed when the last reference to the stream is dropped, but shutdown happens right away — use this to abandon a connection that is in an unknown protocol state (e.g. after an error mid-conversation), especially for streams acquired from a Pool.

pool! : { host : Str, port : U16, max_connections : U64 } => Pool

Create a connection pool for the given address. Creating a pool does not connect; connections are dialed lazily by [Tcp.pool_acquire!].

max_connections bounds the TOTAL number of connections the pool will have open at once (checked out + idle), like Axum/sqlx's max_connections. When the pool is at the cap, [Tcp.pool_acquire!] waits for a release instead of dialing, and fails with TcpConnectErr(TimedOut) if none frees up within 30 seconds. Idle connections unused for 10 minutes are closed and re-dialed on demand.

The Pool value is an immutable handle to host-managed state, so it can be passed around freely and acquired from concurrently.

pool_acquire! : Pool => Try({ stream : Stream, fresh : Bool, metadata : List(U8) }, [TcpConnectErr(ConnectErr), ..])

Check a connection out of the pool.

Returns a recycled connection (fresh: Bool.false, plus whatever metadata it was released with) when one is available, otherwise dials a new one (fresh: Bool.true, empty metadata). If the pool is at max_connections, waits up to 30s for a release, then fails with TcpConnectErr(TimedOut).

metadata is a caller-owned blob stored with the idle connection at [Tcp.pool_release!] time — protocol libraries use it to persist per-connection session state (e.g. Postgres backend keys) across checkouts.

Every acquired stream should be either [Tcp.pool_release!]d (to be reused) or dropped/[Tcp.close!]d — a dropped stream frees its pool slot when the last reference goes away.

pool_release! : { stream : Stream, metadata : List(U8) } => {  }

Return a connection to its pool for another checkout to reuse, storing metadata alongside it. Only release connections that are in a known-good protocol state; after an error mid-conversation, use [Tcp.close!] instead.

connect_err_to_str : [
    AddrInUse,
    AddrNotAvailable,
    ConnectionRefused,
    Interrupted,
    PermissionDenied,
    TimedOut,
    Unsupported,
    Unrecognized(
        a,
    ),
] -> Str

Convert a ConnectErr to a Str you can print.

stream_err_to_str : [
    BrokenPipe,
    ConnectionRefused,
    ConnectionReset,
    Interrupted,
    OutOfMemory,
    PermissionDenied,
    StreamNotFound,
    Unrecognized(
        a,
    ),
] -> Str

Convert a StreamErr to a Str you can print.

Stream

Tcp.Stream :: # (opaque)

Represents a TCP stream.

The connection is automatically closed when the last reference to the stream is dropped. It wraps an opaque host-side BufReader<TcpStream> handle.

to_inspect : Stream -> Str

Render the stream without exposing its host handle.

read_exactly! : Stream, U64 => Try(List(U8), _)

Read an exact number of bytes or fail.

TcpUnexpectedEOF is returned if the stream ends before the specified number of bytes is reached.

read_until! : Stream, U8 => Try(List(U8), _)

Read until a delimiter or EOF is reached. If found, the delimiter is included as the last byte.

read_line! : Stream => Try(Str, _)

Read until a newline (\n, byte 10) or EOF is reached as UTF-8. If found, the newline is included as the last character.

write_utf8! : Stream, Str => Try({  }, _)

Write a string to this TCP stream, encoded as UTF-8.

Pool

Tcp.Pool :: # (opaque)

A host-managed pool of TCP connections to one address (see [Tcp.pool!]).

to_inspect : Pool -> Str

Render the pool without exposing its host handle.

ConnectErr : [
    PermissionDenied,
    AddrInUse,
    AddrNotAvailable,
    ConnectionRefused,
    Interrupted,
    TimedOut,
    Unsupported,
    Unrecognized(Str),
]

Represents errors that can occur when connecting to a remote host.

StreamErr : [
    StreamNotFound,
    PermissionDenied,
    ConnectionRefused,
    ConnectionReset,
    Interrupted,
    OutOfMemory,
    BrokenPipe,
    Unrecognized(Str),
]

Represents errors that can occur when performing an effect with a Stream.