Sign in

    moonbitstack/moonzero/redis does not have a README file

    RedisConn

    pub(open) trait RedisConn {
    async fn execute(Self, Array[Bytes]) -> RespValue
    }

    A live redis connection: it sends an encoded command (an array of argument byte strings) and returns the decoded reply. Implementations own the transport — a real socket speaking RESP, or an in-memory fake. It is open and async so that a socket can be one: real redis I/O suspends, and a sealed synchronous trait left every implementation a test double.

    RedisError

    pub(all) suberror RedisError {
    RedisError(String)
    }

    A redis command that failed — a connection-level error, or a redis error reply.

    RespError

    pub suberror RespError {
    RespError(String)
    }

    A malformed or truncated RESP frame.

    RedisClient

    pub struct RedisClient {
    conn : &RedisConn
    }

    A redis client over a RedisConn, exposing the typed commands the discovery driver uses. Every command maps a redis error reply to RedisError.

    RedisClient::command

    async fn RedisClient::command(self : RedisClient, args : Array[Bytes]) -> RespValue raise RedisError

    Send args as a command and return the reply, turning a connection failure or a redis -ERR reply into RedisError.

    RedisClient::del

    async fn RedisClient::del(self : RedisClient, keys : Array[Bytes]) -> Int64 raise RedisError

    DEL key...: delete the given keys, returning how many existed (deregistration).

    RedisClient::eval

    async fn RedisClient::eval(self : RedisClient, source : String, keys : Array[Bytes], args : Array[Bytes]) -> RespValue raise RedisError

    EVAL source numkeys key... arg...: run a Lua script server-side, where the whole script travels with the call.

    RedisClient::evalsha

    async fn RedisClient::evalsha(self : RedisClient, sha : String, keys : Array[Bytes], args : Array[Bytes]) -> RespValue raise RedisError

    EVALSHA sha numkeys key... arg...: run a script the server already holds. A server that has forgotten it answers NOSCRIPT, which surfaces as a RedisError.

    RedisClient::expire

    async fn RedisClient::expire(self : RedisClient, key : Bytes, ttl_secs : Int) -> Bool raise RedisError

    EXPIRE key ttl: refresh a key's expiry (the discovery keep-alive). true if the key existed and its TTL was set.

    RedisClient::get

    async fn RedisClient::get(self : RedisClient, key : Bytes) -> Bytes? raise RedisError

    GET key: the value at key, or None if the key is absent or expired.

    RedisClient::new

    fn RedisClient::new(conn : &RedisConn) -> RedisClient

    A client over conn.

    RedisClient::ping

    async fn RedisClient::ping(self : RedisClient) -> String raise RedisError

    PING: the server's PONG liveness reply.

    RedisClient::scan_match

    async fn RedisClient::scan_match(self : RedisClient, pattern : Bytes, count : Int) -> Array[Bytes] raise RedisError

    SCAN-iterate every key matching pattern (a glob like prefix/*), following the cursor to completion so the whole keyspace is covered without ever blocking the server on a KEYS scan. count is the per-step hint passed to redis.

    RedisClient::script_load

    async fn RedisClient::script_load(self : RedisClient, source : String) -> String raise RedisError

    SCRIPT LOAD source: put source in the server's script cache and return the SHA1 it answers to from then on.

    RedisClient::set_ex

    async fn RedisClient::set_ex(self : RedisClient, key : Bytes, value : Bytes, ttl_secs : Int) -> Unit raise RedisError

    SET key value EX ttl: store value at key with a ttl-second expiry, the lease a registered instance is held alive by.

    RedisDiscovery

    pub struct RedisDiscovery {
    client : RedisClient
    prefix : String
    seen : Map[String, Array[
    Endpoint
    ]]
    }

    A redis-backed service registry / resolver. Instances of one service live under <prefix><service>/, one key per instance keyed by its dial address, so a SCAN of that prefix returns them all.

    RedisDiscovery::deregister

    async fn RedisDiscovery::deregister(self : RedisDiscovery, service : String) -> Unit

    Deregister every instance of service (delete the whole service prefix).

    RedisDiscovery::deregister_instance

    async fn RedisDiscovery::deregister_instance(self : RedisDiscovery, service : String, endpoint :
    Endpoint
    ) -> Unit

    Deregister one instance of service by deleting its key.

    RedisDiscovery::keepalive

    async fn RedisDiscovery::keepalive(self : RedisDiscovery, service : String, endpoint :
    Endpoint
    , ttl? : Int) -> Bool

    Refresh an instance's lease, extending its key's expiry by ttl seconds. false if the key had already lapsed (the instance must re-register).

    RedisDiscovery::last

    The endpoints the last resolve of service found, without going to redis.

    RedisDiscovery::new

    fn RedisDiscovery::new(client : RedisClient, prefix? : String) -> RedisDiscovery

    A redis discovery over client; keys live under prefix (default "moonzero/").

    RedisDiscovery::register

    async fn RedisDiscovery::register(self : RedisDiscovery, service : String, endpoint :
    Endpoint
    , ttl? : Int) -> String

    Register endpoint for service with a ttl-second lease and return its instance key. Renew it with keepalive before the TTL lapses to stay registered; let it lapse and redis drops the key, deregistering the instance automatically.

    RedisDiscovery::resolve

    Resolve service to its live endpoints: SCAN the service prefix and read each instance's value as its host:port endpoint. Keys that lapse mid-scan and malformed values are skipped. The answer is also kept as the service's last known set, which is what resolver hands a balancer.

    RedisDiscovery::resolver

    This redis discovery as a Resolve interface value, so the balancer and the load-balanced channel run against redis unchanged. Resolve is synchronous and a SCAN over a socket is not, so the closure reads the set the last resolve of that service found — the same arrangement discov's file registry uses, where the async reload and the synchronous resolve are separate steps. A service not resolved yet balances over nothing.

    RedisScript

    pub struct RedisScript {
    source : String
    sha : String?
    }

    A Lua script bound to its SHA1 (← go-redis's Script, the shape go-zero's ScriptRun drives). The first run SCRIPT LOADs the source and keeps the digest, every later run is an EVALSHA that ships a 40-byte hash instead of the whole program, and a server that has forgotten it — a restart, a SCRIPT FLUSH — answers NOSCRIPT, which loads it again and retries once.

    RedisScript::new

    fn RedisScript::new(source : String) -> RedisScript

    A script over source, not yet loaded anywhere.

    RedisScript::run

    async fn RedisScript::run(self : RedisScript, client : RedisClient, keys : Array[Bytes], args : Array[Bytes]) -> RespValue raise RedisError

    Run the script on client over keys and args, loading it first if its digest is not known yet or the server has dropped it.

    RedisScript::source

    fn RedisScript::source(self : RedisScript) -> String

    The Lua this script runs.

    RespReader

    pub struct RespReader {
    data : Bytes
    pos : Int
    }

    A cursor over a RESP byte stream, decoding one value at a time. A socket client feeds it a buffered reply; read advances past exactly one value, so several pipelined replies decode in sequence.

    RespReader::at_end

    fn RespReader::at_end(self : RespReader) -> Bool

    Whether every byte has been consumed.

    RespReader::new

    fn RespReader::new(data : Bytes) -> RespReader

    A reader positioned at the start of data.

    RespReader::read

    fn RespReader::read(self : RespReader) -> RespValue raise RespError

    Decode the next RESP value, advancing the cursor past it.

    RespValue

    pub(all) enum RespValue {
    SimpleString(String)
    Error(String)
    Integer(Int64)
    BulkString(Bytes)
    Null
    Array(Array[RespValue])
    Boolean(Bool)
    Double(Double)
    BigNumber(String)
    BulkError(String)
    VerbatimString(String, Bytes)
    RespMap(Array[(RespValue, RespValue)])
    RespSet(Array[RespValue])
    Push(Array[RespValue])
    } derive(Eq,
    Debug
    )

    A decoded RESP value. RESP2's null bulk string ($-1) and null array (*-1) both decode to Null, unifying with RESP3's explicit null (_). BulkString carries raw bytes (redis values are binary-safe); the text-line types carry the decoded string.

    RespValue::decode

    fn RespValue::decode(data : Bytes) -> RespValue raise RespError

    Decode exactly one RESP value from data, requiring it to consume the whole input. Trailing bytes after a complete value are a framing error.

    RespValue::equal

    fn RespValue::equal(RespValue, RespValue) -> Bool

    RespValue::not_equal

    fn RespValue::not_equal(x : RespValue, y : RespValue) -> Bool

    redis_instance_key

    fn redis_instance_key(prefix : String, service : String, endpoint :
    Endpoint
    ) -> String

    The key one instance of service lives at: <prefix><service>/<address>.

    redis_service_pattern

    fn redis_service_pattern(prefix : String, service : String) -> String

    The SCAN MATCH glob for every instance of service: <prefix><service>/*.

    redis_service_prefix

    fn redis_service_prefix(prefix : String, service : String) -> String

    The key prefix a service's instances live under: <prefix><service>/. Exposed so the native RESP-socket path builds the exact same keys as the in-process driver.

    resp_command

    fn resp_command(args : Array[String]) -> Bytes

    Encode a command given string arguments (the common case — command names and keys are text), UTF-8 encoding each.

    resp_encode_command

    fn resp_encode_command(args : Array[Bytes]) -> Bytes

    Encode a command as the client frame redis expects: an array of bulk strings, one per argument (*<n>\r\n$<len>\r\n<arg>\r\n...). Arguments are raw bytes, so binary keys and values round-trip unchanged.

    resp_kind

    fn resp_kind(value : RespValue) -> String

    A short name for a value's RESP type, for error messages ("unexpected <kind> reply") — RespValue derives Eq/Debug but not a renderable form.