feat(client): close gRPC API gap — 31 new commands + pub/sub subscriber + vector commands - #304
Merged
Conversation
adds a full typed command API and pipeline builder on top of the existing raw `send()` method. no new crate — the types layer cleanly on what's there. commands covered: get/set/set_ex/del/exists/expire/persist/ttl/pttl/ incr/decr/incrby/decrby/append/mget/mset/getdel (strings), lpush/rpush/ lpop/rpop/lrange/llen (lists), hset/hget/hgetall/hdel/hexists/hlen/hkeys/ hvals (hashes), sadd/srem/smembers/sismember/scard (sets), zadd/zrange/ zrange_withscores/zscore/zrank/zrem/zcard (sorted sets), ping/dbsize/flushdb. `Pipeline` is a chainable builder that writes all frames in a single syscall and reads responses sequentially, keeping pipelining cost to one flush per batch. `ClientError::Server` is new — server-returned errors (`WRONGTYPE`, etc.) are now distinct from wire-level `Protocol` errors.
closes the gap between the typed rust client and the server's full command set. mechanical additions, all following existing patterns. new decoders: - string_value: simple/bulk → String (TYPE, INFO, ECHO, BGSAVE) - float_value: bulk float string → f64 (INCRBYFLOAT) - scan_page: Array([cursor, [keys]]) → ScanPage (SCAN) - slowlog_entries: Array of entry arrays → Vec<SlowlogEntry> (SLOWLOG GET) - numsub_pairs: interleaved ch/count array → Vec<(Bytes, i64)> (PUBSUB NUMSUB) new public types: ScanPage, SlowlogEntry (re-exported from lib.rs) new Client methods: - strlen, incr_by_float - key_type, keys, rename, scan, pexpire - hmget - echo, unlink, info, bgsave, bgrewriteaof - slowlog_get, slowlog_len, slowlog_reset - publish, pubsub_channels, pubsub_numsub, pubsub_numpat new Pipeline builder methods for all new commands integration tests covering all new commands
adds a dedicated subscriber connection type that wraps a Client once it enters pub/sub mode. regular request-response commands cannot be issued on the same connection while subscribed — callers use a separate Client. new types: Subscriber, Message (re-exported from lib.rs) new Client methods: - subscribe(channels) → Subscriber - psubscribe(patterns) → Subscriber Subscriber methods: - recv() — waits for the next message, skips confirmation frames - subscribe(channels) — add more channels without leaving sub mode - unsubscribe(channels) → Client — remove channels and reclaim connection connection.rs: added write_frame() and pub(crate) read_response() so Subscriber can drive the connection directly integration tests: subscriber_recv_message, subscriber_multiple_channels, psubscriber_pattern_match
adds VADD, VADD_BATCH, VSIM, VREM, VGET, VCARD, VDIM, VINFO to the
typed client API, gated behind the new 'vector' cargo feature.
new public type: SimResult { element: Bytes, distance: f32 }
new Client methods (cfg(feature = "vector")):
- vadd(key, element, vector) → bool
- vadd_batch(key, dim, entries) → i64
- vsim(key, query, count) → Vec<SimResult> (always WITHSCORES)
- vrem(key, element) → bool
- vget(key, element) → Option<Vec<f32>>
- vcard(key) → i64
- vdim(key) → i64
- vinfo(key) → Vec<(Bytes, Bytes)>
floats are encoded as decimal strings in RESP3, matching the server's
wire format. VADD_BATCH uses the text mode (DIM n then element floats);
binary blob mode is not exposed since it's a platform-specific concern.
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.
summary
closes the gap between the typed rust client (
ember-client) and the server's full command set. before this PR the client exposed 34 commands; afterwards it covers every server-side command except the cluster and migrate commands (which are routing-layer concerns, not application-layer).PR A — mechanical command additions (3 commits for context; shipped as one PR)
string_value,float_value,scan_page,slowlog_entries,numsub_pairsScanPage,SlowlogEntryClientmethods across strings, keys, hashes, server, slowlog, and pub/subPipelinebuilder methods for all new commandsPR B — pub/sub subscriber mode
Subscribertype +MessagetypeClient::subscribeandClient::psubscribeconsume the connection and return aSubscriberSubscriber::recvwaits for the next pushed message, skipping confirmation framesSubscriber::subscribeadds channels without leaving sub modeSubscriber::unsubscriberemoves channels and returns theClientfor reusePR C — vector commands (
vectorfeature flag)vectormodule withSimResulttypevadd,vadd_batch,vsim,vrem,vget,vcard,vdim,vinfovsimalways uses WITHSCORES for a consistent return typewhat was tested
cargo build -p ember-client(default features, no warnings)cargo build -p ember-client --features vector(no warnings)cargo clippy -p ember-client --features vector -- -D warnings(clean)cargo test -p ember-client --features vector(21 unit + 5 doc tests, all pass)cargo build --test integration(no warnings on integration test crate)cargo fmt --all --check(clean)design notes
Subscriberwraps theClientdirectly rather than owning a raw transport. this keeps TLS support automatic — anyClient(TCP or TLS) can become aSubscriberread_response()is nowpub(crate)andwrite_frame()was added soSubscribercan drive the connection without going throughsend_frame's request-response couplingvadd_batchuses DIM text mode (not binary blob mode) to keep the API platform-independent