feat(valkey): initial stable release v0.9.0
Valkey (Redis-compatible) client component with launcher lifecycle and health check integration. What's included: - Config with Addrs, Password, SelectDB, CacheSizeEachConn (env-driven) - Provider interface exposing native valkey-go Client() directly (no wrapper) - Component interface: launcher.Component + health.Checkable + Provider - New(logger, cfg) constructor for lifecycle registration via lc.Append - Health check via PING at LevelDegraded priority - Graceful shutdown calling client.Close() in OnStop Tested-via: todo-api POC integration Reviewed-against: docs/adr/
This commit is contained in:
92
CLAUDE.md
Normal file
92
CLAUDE.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# valkey
|
||||
|
||||
Valkey (Redis-compatible) client with launcher lifecycle and health check integration.
|
||||
|
||||
## Purpose
|
||||
|
||||
Manages the lifecycle of a `valkey-go` client: constructs it from config, verifies
|
||||
connectivity at startup, exposes the native client to consumers, and closes it on shutdown.
|
||||
Provides a health check via `PING`. Does not add serialisation, key namespacing, or any
|
||||
caching policy on top of the native client.
|
||||
|
||||
## Tier & Dependencies
|
||||
|
||||
**Tier 3 (infrastructure)** — depends on:
|
||||
- `code.nochebuena.dev/go/health` (Tier 2)
|
||||
- `code.nochebuena.dev/go/launcher` (Tier 2)
|
||||
- `code.nochebuena.dev/go/logz` (Tier 1)
|
||||
- `github.com/valkey-io/valkey-go` (native Valkey client)
|
||||
|
||||
Does **not** depend on `xerrors` — errors from the valkey-go client are returned as-is.
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
- **Native client exposure**: `Client() vk.Client` returns the native `valkey-go` client
|
||||
directly. No wrapper, no re-exported command subset. Callers use the full valkey-go command
|
||||
builder API. See ADR-001.
|
||||
- **No serialisation helpers**: The module has no `SetJSON`, `GetJSON`, or similar helpers.
|
||||
Callers marshal and unmarshal their own data. See ADR-002.
|
||||
- **Health priority is Degraded**: `Priority()` returns `health.LevelDegraded`, not
|
||||
`LevelCritical`. A Valkey outage degrades service but should not always halt it,
|
||||
depending on whether the caller falls back to the primary datastore.
|
||||
- **Optional client-side caching**: `Config.CacheSizeEachConn` (in MB) enables valkey-go's
|
||||
built-in client-side cache. Setting it to 0 (the default) disables the cache entirely.
|
||||
- **Duck-typed Logger**: The internal `logger` field is typed as `logz.Logger`, the shared
|
||||
interface from the `logz` module (ADR-001 global pattern).
|
||||
|
||||
## Patterns
|
||||
|
||||
**Lifecycle registration:**
|
||||
```go
|
||||
vk := valkey.New(logger, cfg)
|
||||
lc.Append(vk) // registers OnInit / OnStart / OnStop
|
||||
```
|
||||
|
||||
**Accessing the client in a repository:**
|
||||
```go
|
||||
type cacheRepo struct {
|
||||
provider valkey.Provider
|
||||
}
|
||||
|
||||
func (r *cacheRepo) Get(ctx context.Context, key string) ([]byte, error) {
|
||||
client := r.provider.Client()
|
||||
result := client.Do(ctx, client.B().Get().Key(key).Build())
|
||||
return result.AsBytes()
|
||||
}
|
||||
```
|
||||
|
||||
**Writing with TTL:**
|
||||
```go
|
||||
client := provider.Client()
|
||||
cmd := client.B().Set().Key(key).Value(val).Ex(300).Build()
|
||||
if err := client.Do(ctx, cmd).Error(); err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
**Health check registration:**
|
||||
```go
|
||||
health.Register(vkComponent) // satisfies health.Checkable via Name()/Priority()/HealthCheck()
|
||||
```
|
||||
|
||||
## What to Avoid
|
||||
|
||||
- Do not add serialisation helpers to this module. Keep marshal/unmarshal in the caller or
|
||||
in a separate cache repository layer.
|
||||
- Do not define custom interfaces that re-export a subset of `vk.Client` methods here.
|
||||
If a consumer needs a minimal testable interface, define it in the consumer package.
|
||||
- Do not call `Client()` before `OnInit` has run — it will return `nil`.
|
||||
- Do not treat `health.LevelDegraded` as if it were `LevelCritical`. Design callers to
|
||||
handle cache misses gracefully rather than depending on Valkey for correctness.
|
||||
|
||||
## Testing Notes
|
||||
|
||||
- Unit tests (`valkey_test.go`) do not require a running Valkey server. They test lifecycle
|
||||
behaviour (nil client safety, name, priority) without real network calls.
|
||||
- `TestComponent_OnInit_InvalidAddr` verifies that an empty address slice does not panic.
|
||||
Whether `OnInit` returns an error depends on the valkey-go implementation; the test
|
||||
documents the accepted behaviour.
|
||||
- Integration tests requiring a live Valkey instance are outside this module and belong in
|
||||
a higher-tier test suite.
|
||||
- `compliance_test.go` (package `valkey_test`) asserts `New(...)` satisfies `Component`
|
||||
at compile time.
|
||||
Reference in New Issue
Block a user