Repository navigation
Rebuild the client around connections, transports and commands - #90
Merged
Merged
Conversation
Replace the `store` interface, a connection resource carrying every command, with interfaces that separate the mechanics of talking to a server from the transport carrying it and from the commands sent over it. Connections always speak RESP3. WIT, componentized:valkey: - `connection`: request/reply over a pair of value streams, for any transport. `new` returns the requests stream and a future resolving to the connection once `HELLO 3` succeeds, which pins RESP3 and confirms the server can be reached. `call` pairs replies with commands in order with several in flight, `send` is fire and forget, `pushes` broadcasts push messages to every reader, closing a reader that falls behind rather than holding up replies, `set-keep-alive` pings an idle connection - `tcp`: connections over wasi:sockets, a `transport` resource and `connect` - `connector`: connections whose transport and settings are chosen by the provider - command interfaces for each of Valkey's ACL categories, e.g. `hash-commands`, functions borrowing a connection so each category can be implemented independently. The commands not yet implemented are listed in each interface - `store` is removed Components: - `resp`: exports the RESP codec, the types every component shares - `connection`, `tcp` and `tcp-connector`, which connects to the server configured with wasi:config, with keys `hostname`, `port`, `username`, `password`, `client-name` and `keep-alive-interval-ms` - `commands`, every command interface in one component, and a component for each category, e.g. `hash-commands`, compiled from the shared sources in crates/commands - `as-keyvalue` gets connections from a `connector`, rather than connecting over TCP itself - `cli` and `client` are composed from the new components - `ops` is removed RESP: - the codec moves to crates/resp-codec, a regular crate the components share through wit-bindgen's `with` - messages that span several socket reads are framed before they are decoded, bytes past a message are kept for the next - nested values are copied as received, rather than decoded and encoded again Tests: - crates/test-harness instantiates components with wasmtime, and plays the server over a stub transport, or over TCP - the tests against a Valkey server are ignored unless run with `make test-valkey`, which CI runs after `make test` - CI and the dev container use Valkey 9, which as-keyvalue's ttls need for HEXPIRE Signed-off-by: Scott Andrews <scott@andrews.me> Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Run tests against a real ephemeral valkey-severs running in docker. Signed-off-by: Scott Andrews <scott@andrews.me>
Skip non-essential features, like pub/sub. Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
BulkStrings cary double duty as actual utf-8 encoded strings and binary blobs. we now handle both cases. Any value that can be decodded as a string is returned as a string, otherwise the bytes are provided. When sending commands, either form is acceptable. Command values that are aways strings remain strings. Values that are always binary are list<u8> and values that may alternate depending on the content or context are the string-or-bytes variants. Users will need to detect which form was returned. Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
The `tcp-connector-latch` limits network access to only the essential capabilities necessary to establish a connection with the `tcp-connector`. In order, it will only lookup IP address for the configured hostname. TCP sockets can only connect to the IP address returned by the hostname lookup, on the port specified by the config. No inbound connections are allow, nor any UDP activity. The gate and latch are installed by default into the `cli` component as that uses the `tcp-connector`. Other users of the `tcp` transport will need to configure a latch appropriate for their environment. Signed-off-by: Scott Andrews <scott@andrews.me>
scothis
marked this pull request as ready for review
October 15, 2026 23:45
The tests that need a server spin up an ephemeral container. Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
scothis
enabled auto-merge (squash)
October 16, 2026 02:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replace the
storeinterface and theopscomponent with acomponentized:valkey@0.3.0-devpackage that separates the mechanics ofa connection from the transport carrying it, and from the commands sent
over it. Connections always speak RESP3.
connection: pairs commands with replies, keeps push messages apart,re-establishes state after RESET, and advertises the client's name and
version. Pub/sub, transactions and WATCH are part of the connection,
with a
subscriptionresource for channels, patterns and shardchannels.
connection-minimalis the same interface without pub/sub,for a smaller component.
tcpandtcp-connector: connections overwasi:socketsto the server.The connector defines a no-arg method to establish a pre-configured (via
wasi:config) connection.commands: typed functions for Valkey's command set, followingValkey's command definitions, with the shared types in a
typesinterface. Values are
string,bytesorstring-or-bytes, sobinary data round trips.
componentized-valkeycrate: the types, the RESP codec and theconversions between commands, replies and the WIT types, shared by
the components.
Network access can be limited with
componentized:socketsgates.tcp-connector-latchallows only the server in the connector's config(its hostname, by name or IP address, on its port, over TCP) and denies
every other socket. The
cliis always behind a gate with this latch,composed so that components behind the gate cannot import wasi:sockets
around it.
Tests run components in wasmtime with a shared harness. Guest-side
suites cover the commands and the latch, the latch over stub sockets so
that denials are certain.
make test-valkeyruns the integration testsagainst Valkey in a Docker container.