# cask-redis **Repository Path**: ghink/cask-redis ## Basic Information - **Project Name**: cask-redis - **Description**: Redis driver for cask - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-08 - **Last Updated**: 2026-06-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # cask-redis Redis driver for [cask](https://go.gh.ink/cask). This module implements the `cask` driver/adapter contract on top of [`go-redis/v9`](https://github.com/redis/go-redis). Importing it registers a `"redis"` driver that `cask.New` will automatically select whenever it is given a `*redis.Client`. ## Installation ```sh go get go.gh.ink/cask/redis ``` ## Usage The driver registers itself in `init()`, so a blank import is all that is needed — you never call into this package directly. Pass a `*redis.Client` to `cask.New` and you get a namespace backed by Redis. ```go package main import ( "context" "fmt" "github.com/redis/go-redis/v9" "go.gh.ink/cask" "go.gh.ink/cask/model" _ "go.gh.ink/cask/redis" // side-effect import: registers the "redis" driver "go.gh.ink/timex" ) func main() { root, err := cask.New(redis.NewClient(&redis.Options{ Addr: "localhost:6379", DB: 0, }), "cask-test") if err != nil { panic(err) } ns := root.Namespace("test1") // Redis key: "cask-test:test1" ctx := context.Background() // Store with no expiration (positive-infinite duration). _ = ns.Set(ctx, []byte("value1"), timex.NewPosInfDuration()) ok, _ := ns.Exists(ctx) fmt.Println(ok) // true val, _ := ns.Get(ctx) fmt.Println(string(val)) // value1 // Expiration support is exposed through the optional model.Expirer interface. exp := ns.Adapter.(model.Expirer) _ = exp.Expire(ctx, timex.FromStdDuration(60*1e9)) // 60s ttl, _ := exp.TTL(ctx) fmt.Println(ttl) } ``` A runnable demo lives in [`test/main.go`](test/main.go). ## What it provides The Redis `Adapter` wraps a `*redis.Client` and uses the namespace's `Key()` as the Redis key. It implements both the required `BaseStore` and the optional `Expirer` interface from `cask/model`: | Method | Redis operation | | ---------------------------- | ---------------------------------------- | | `Get(ctx)` | `GET key` (returned as `[]byte`) | | `Set(ctx, value, ttl)` | `SET key value PX ` | | `Del(ctx)` | `DEL key` (`true` when ≥1 key removed) | | `Exists(ctx)` | `EXISTS key` (`true` when key present) | | `Expire(ctx, ttl)` | `PEXPIRE` / `PERSIST` / `DEL` (see below) | | `TTL(ctx)` | `TTL key` (mapped to a `timex.Duration`) | ## TTL semantics Durations are expressed with [`timex.Duration`](https://go.gh.ink/timex), which can represent finite, zero, and infinite values. The driver translates these into Redis behavior (see [`timex.go`](timex.go) and the `Expire` implementation in [`adapter.go`](adapter.go)): **On `Set` / `ToSetPXDuration`:** | `timex.Duration` | Effect | | --------------------------- | ------------------------------------------------------ | | Positive-infinite | No expiration (`PX 0` → persistent) | | Finite and `> 0` | Set with that exact expiry | | Zero / negative / neg-inf | Expire (almost) immediately (min 1ms) | **On `Expire`:** | `timex.Duration` | Effect | | --------------------------- | ------------------------------------------------------ | | Positive-infinite | `PERSIST` — remove expiration | | Finite and `> 0` | `PEXPIRE` (clamped to a minimum of 1ms) | | Zero / negative / neg-inf | `DEL` — remove the key | **On `TTL` / `FromTTLDuration`:** Redis's special return codes are mapped back to infinite durations: | Redis `TTL` result | Returned `timex.Duration` | | ------------------ | -------------------------------- | | `-2` (no key) | negative-infinite | | `-1` (no expiry) | positive-infinite | | `≥ 0` | finite duration | ## Source layout | File | Responsibility | | ------------- | --------------------------------------------------------------------- | | `driver.go` | `Driver.NewAdapter` — type-asserts the client to `*redis.Client`. | | `adapter.go` | `Adapter` — Redis-backed implementation of `BaseStore` + `Expirer`. | | `register.go` | `init()` that registers the driver under the name `redis`. | | `const.go` | The driver name constant (`Name = "redis"`). | | `timex.go` | Conversions between `timex.Duration` and Redis durations/TTL codes. | | `test/` | A small `main` program exercising the driver against a live Redis. | ## License Apache License 2.0. See [LICENSE](LICENSE).