A transport for connections over wasi:sockets TCP.
Types
use record connect-optssince 0.3.0-dev
from componentized:valkey/types@0.3.0-dev
Options for establishing a connection.
auth:option<tuple<string, string>>The username and password to authenticate with.
client-name:option<string>The name of the connection, see
CLIENT SETNAME.keep-alive-interval:option<duration-milliseconds>Enables keep-alive pings at this interval, see
connection.set-keep-alive.
use variant error-codesince 0.3.0-dev
from componentized:valkey/types@0.3.0-dev
connection The errors of a connection and of every command interface.
closed:option<string>The transport closed while a reply was outstanding, or before the command was sent. Holds the transport's error when it did not close gracefully.
client:stringClient errors are semantic issues with input/output values, e.g. a reply that does not have the shape the command expects.
resp:resp-errorRESP errors are encoding issues converting values to/from bytes.
server:string-or-bytesServer errors are Error or BulkError RESP values returned directly from the server. An Error is a string, a BulkError a string when it is UTF-8, bytes otherwise.
laggedThe reader of a stream fell too far behind and its stream was closed, rather than holding up the connection. What the stream missed is lost.
use variant resp-valuesince 0.3.0-dev
from componentized:valkey/types@0.3.0-dev
string:stringerror:stringinteger:integerbulk-string:bytesarray:list<resp-nested-value>nullboolean:booldouble:doublebig-number:stringbulk-error:bytesverbatim-string:tuple<string, string>map:list<tuple<resp-nested-value, resp-nested-value>>set:list<resp-nested-value>push:list<resp-nested-value>
use resource connectionsince 0.3.0-dev
from componentized:valkey/connection@0.3.0-dev
new: static async func( replies: stream<resp-value>, closed: future<result<_, error-code>>, opts: option<connect-opts>, ) -> tuple<stream<resp-value>, future<result<connection, error-code>>>since 0.3.0-devEstablishes a connection over a transport.
repliesare the values the transport receives from the server, andclosedresolves when the transport closes, tookfor a graceful close or to the error otherwise, seetcp.transport.receive. Returns the requests for the transport to write to the server, in order, and the connection once it is established.The connection sends
HELLO 3, with theauthandclient-nameofopts, as its first command. This pins the connection to RESP3 and confirms the server can be reached. The future resolves to the connection once HELLO succeeds, or to the error that stopped it. The rest ofoptsis applied before the connection is returned.It then reports the library to the server,
CLIENT SETINFO LIB-NAME componentized:valkeyandLIB-VERwith the version of the package, ignoring an error from a server that does not know CLIENT SETINFO. They survivereset,client-setinforeplaces them.Async so the connection keeps working between commands after it returns, e.g. to read push messages and to send keep-alive pings.
server-properties: func() -> list<tuple<string, resp-value>>since 0.3.0-devThe server's properties from the reply to HELLO, e.g.
server,versionandmode.exchange: async func( command: list<string-or-bytes>, ) -> result<resp-value, error-code>since 0.3.0-devSends a command and waits for its reply.
Several commands may be in flight at once, replies are paired with commands in the order the commands were sent.
For SUBSCRIBE, PSUBSCRIBE, SSUBSCRIBE and their UNSUBSCRIBE counterparts, prefer a
subscription, which owns its targets' messages. Once the connection has one, it alone sends these commands, and they fail with a client error before anything is sent, here, withexchange-all,emitandtransaction.RESET, HELLO and CLIENT REPLY always fail with a client error. See
resetandserver-properties, CLIENT REPLY would stop replies from pairing with commands, seeemit.A command has at least one word, an empty command fails with a client error.
exchange-all: async func( commands: list<list<string-or-bytes>>, ) -> list<result<resp-value, error-code>>since 0.3.0-devSends the commands one after another, with no other command sent between them, and waits for every reply.
Each command has its own result, in order, as if each was sent with
exchange. Commands sharing a connection may otherwise be interleaved with other callers' commands, which matters for a sequence that must not be interrupted, e.g. MULTI, its commands and EXEC.emit: async func( command: list<string-or-bytes>, ) -> result<_, error-code>since 0.3.0-devSends a command without waiting for its reply, resolving once the command is written.
The server still replies, the reply is discarded when it arrives and an error it reports is not returned. An implementation may instead ask the server not to reply, e.g. with
CLIENT REPLY SKIP.A command has at least one word, an empty command fails with a client error.
watch: async func(keys: list<string>) -> result<_, error-code>since 0.3.0-devMarks the keys to watch, EXEC aborts the next transaction when any of them changed.
Watched keys belong to the connection, and EXEC, DISCARD or UNWATCH from any caller sharing it clears them. Use a connection of your own for WATCH, the reads it guards, and the transaction.
WATCH key [ key ... ] https://valkey.io/commands/watch/
At least one key, no keys fails with a client error.
unwatch: async func() -> result<_, error-code>since 0.3.0-devForgets all the watched keys.
UNWATCH https://valkey.io/commands/unwatch/
transaction: async func( commands: list<list<string-or-bytes>>, ) -> result<option<list<resp-value>>, error-code>since 0.3.0-devRuns the commands as a transaction, MULTI, each command, then EXEC, with no other command sent between them, see
exchange-all.Returns none when a watched key changed and the transaction was aborted, otherwise the reply of each command in order. A command that fails while running is an error value in its place, the others still ran. A command rejected while queuing, e.g. an unknown command, fails the transaction with that error, none of the commands ran.
MULTI and EXEC are only sent as part of a transaction, the commands between them reply QUEUED rather than their reply.
MULTI, EXEC https://valkey.io/commands/multi/ https://valkey.io/commands/exec/
subscription: func() -> result<subscription, error-code>since 0.3.0-devA new subscription, subscribed to nothing yet, see the subscription's
subscribe.From the first subscription, the connection owns its subscriptions: SUBSCRIBE, PSUBSCRIBE, SSUBSCRIBE and their UNSUBSCRIBE counterparts sent with
exchangeand the like fail with a client error, so the server's subscriptions stay in step with the connection's. Subscriptions made withexchangebefore are unsupported. They may keep delivering todead-letters, the exact behavior is undocumented.Fails with a client error when the connection component was built without pub/sub, e.g.
connection-minimal. Its push messages are then all dead letters, and SUBSCRIBE and the like may still be sent withexchange.dead-letters: func() -> stream<resp-value>since 0.3.0-devThe values nothing else claims, kept apart from replies.
Push messages that no subscription owns, e.g. client tracking invalidations, messages and confirmations of SUBSCRIBE sent with
exchange, or kinds of push messages from a newer server. Values the server sends unprompted, when no command is waiting for a reply, are included, e.g. the feed of MONITOR, which are not RESP push values.Each call returns a new stream that receives every value arriving after the call, values arriving while no stream is open are dropped. A stream that falls too far behind is closed rather than holding up replies, the values it missed are lost.
reset: async func() -> result<_, error-code>since 0.3.0-devResets the connection to the state of a new one, then repeats the handshake of
new.RESET discards a transaction in progress, forgets the watched keys, unsubscribes from every channel, turns off client tracking and the like, selects database 0, and forgets the client name and the authenticated user. It also switches the connection to RESP2, so it is followed at once by
HELLO 3with theauthandclient-namethe connection was established with, with no other command sent between them.server-propertiesthen holds the new reply to HELLO.The subscriptions are unsubscribed from every target, each with the reason
reset, and stay open for new targets.No other command is sent until the handshake succeeds, so none runs on the connection RESET leaves. When the handshake fails, e.g. the credentials expired since the connection was established, the connection closes with its error, and the commands queued after the reset fail with it without being sent. Establish a new connection.
RESET https://valkey.io/commands/reset/
set-keep-alive: func(interval: option<duration-milliseconds>)since 0.3.0-devSends PING when no command has been sent and no reply is outstanding for
interval,nonedisables it. A PING that fails closes the connection. Disabled by default.Unlike TCP keep-alive, a PING counts as activity for the server's idle client timeout, and works over any transport.
resource transportsince 0.3.0-dev
A TCP connection to a Valkey server, framing the bytes it carries into RESP values in each direction.
open: static async func( host: string, port: u16, ) -> result<transport, error-code>since 0.3.0-devOpens a transport to
host, a hostname or an IP address. Each address the host resolves to is tried in turn.send: func( requests: stream<resp-value>, ) -> future<result<_, error-code>>since 0.3.0-devWrites each value from
requeststo the server, in order.May be called at most once, like
tcp-socket.send. Closingrequestshalf-closes the socket. The future resolves once every value is written, or with the error that stopped writing.receive: func() -> tuple<stream<resp-value>, future<result<_, error-code>>>since 0.3.0-devThe values the server sends, in order.
May be called at most once, like
tcp-socket.receive. The stream closes when the server closes the socket, the future resolves tookfor a graceful close or to the error otherwise.
Functions
connect: async func(
host: string,
port: u16,
opts: option<connect-opts>,
) -> result<connection, error-code>since 0.3.0-dev
Opens a transport and establishes a connection over it with opts, see connection.new.
The connection keeps the transport alive.
WIT
/// A transport for connections over wasi:sockets TCP.
interface tcp {
@since(version = 0.3.0-dev)
use types.{connect-opts, error-code, resp-value};
@since(version = 0.3.0-dev)
use connection.{connection};
/// A TCP connection to a Valkey server, framing the bytes it carries into RESP values in each
/// direction.
@since(version = 0.3.0-dev)
resource transport {
/// Opens a transport to `host`, a hostname or an IP address. Each address the host resolves
/// to is tried in turn.
@since(version = 0.3.0-dev)
open: static async func(host: string, port: u16) -> result<transport, error-code>;
/// Writes each value from `requests` to the server, in order.
///
/// May be called at most once, like `tcp-socket.send`. Closing `requests` half-closes the
/// socket. The future resolves once every value is written, or with the error that stopped
/// writing.
@since(version = 0.3.0-dev)
send: func(requests: stream<resp-value>) -> future<result<_, error-code>>;
/// The values the server sends, in order.
///
/// May be called at most once, like `tcp-socket.receive`. The stream closes when the server
/// closes the socket, the future resolves to `ok` for a graceful close or to the error
/// otherwise.
@since(version = 0.3.0-dev)
receive: func() -> tuple<stream<resp-value>, future<result<_, error-code>>>;
}
/// Opens a transport and establishes a connection over it with `opts`, see `connection.new`.
///
/// The connection keeps the transport alive.
@since(version = 0.3.0-dev)
connect: async func(host: string, port: u16, opts: option<connect-opts>) -> result<connection, error-code>;
}