Documentation
¶
Overview ¶
Package rediskit wraps go-redis with cache-aside, a fiber.Storage adapter, pub/sub, and bulk/atomic helpers.
Index ¶
- func ParseRedisOptions(redisURL string) (*redis.Options, error)
- func Remember[T any](ctx context.Context, r *Redis, key string, ttl time.Duration, ...) (T, error)
- type Client
- type Redis
- func (r *Redis) Decr(ctx context.Context, key string) (int64, error)
- func (r *Redis) Delete(ctx context.Context, keys ...string) error
- func (r *Redis) Exists(ctx context.Context, key string) (bool, error)
- func (r *Redis) Expire(ctx context.Context, key string, ttl time.Duration) (bool, error)
- func (r *Redis) Get(ctx context.Context, key string, dest any) error
- func (r *Redis) GetSet(ctx context.Context, key string, value any) (string, error)
- func (r *Redis) Incr(ctx context.Context, key string) (int64, error)
- func (r *Redis) MGet(ctx context.Context, keys ...string) (map[string]string, error)
- func (r *Redis) MSet(ctx context.Context, pairs map[string]any, ttl time.Duration) error
- func (r *Redis) Publish(ctx context.Context, channel string, value any) error
- func (r *Redis) Set(ctx context.Context, key string, value any, expiration time.Duration) error
- func (r *Redis) SetNX(ctx context.Context, key string, value any, ttl time.Duration) (bool, error)
- func (r *Redis) TTL(ctx context.Context, key string) (time.Duration, error)
- type Storage
- func (s *Storage) Close() error
- func (s *Storage) Delete(key string) error
- func (s *Storage) DeleteWithContext(ctx context.Context, key string) error
- func (s *Storage) Get(key string) ([]byte, error)
- func (s *Storage) GetWithContext(ctx context.Context, key string) ([]byte, error)
- func (s *Storage) Reset() error
- func (s *Storage) ResetWithContext(ctx context.Context) error
- func (s *Storage) Set(key string, val []byte, exp time.Duration) error
- func (s *Storage) SetWithContext(ctx context.Context, key string, val []byte, exp time.Duration) error
- type StorageOption
- type Subscription
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseRedisOptions ¶
ParseRedisOptions parses a redis:// URL into options.
func Remember ¶
func Remember[T any](ctx context.Context, r *Redis, key string, ttl time.Duration, loader func() (T, error)) (T, error)
Remember returns the cached value for key, or runs loader on a cache miss, stores its result with ttl, and returns it. A failure to store the loaded value does not fail the call. Concurrent misses for the same key within this process are deduplicated so loader runs once (cache-stampede protection).
Types ¶
type Redis ¶
type Redis struct {
Client *Client
// contains filtered or unexported fields
}
Redis wraps a go-redis client with JSON (de)serialization helpers.
func (*Redis) Decr ¶
Decr atomically decrements the integer value of key by one and returns the new value.
func (*Redis) Delete ¶
Delete removes the given keys. It is a no-op (returns nil) when no keys are given.
func (*Redis) Expire ¶
Expire sets a time-to-live on key. The returned bool reports whether the key existed (and therefore whether the TTL was applied).
func (*Redis) GetSet ¶
GetSet JSON-encodes value, stores it under key, and returns the previous raw value. The returned string is empty (with a redis.Nil error) when key did not exist.
func (*Redis) Incr ¶
Incr atomically increments the integer value of key by one and returns the new value.
func (*Redis) MGet ¶
MGet returns the raw stored value for each key that exists, keyed by key. Missing keys are omitted. Callers unmarshal the raw values themselves.
func (*Redis) MSet ¶
MSet JSON-encodes and stores each pair. When ttl > 0 it is applied to every key. Executed in a single pipeline round-trip.
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage adapts a go-redis client to the fiber.Storage interface (used by the rate limiter and other Fiber middleware). Keys are namespaced with a prefix so Reset is scoped and entries never collide with application cache keys.
func NewStorage ¶
func NewStorage(client *Client, opts ...StorageOption) *Storage
NewStorage adapts client to fiber.Storage.
Example ¶
NewStorage adapts a go-redis client to fiber.Storage, e.g. for a multi-instance rate limiter. miniredis stands in for real Redis here.
package main
import (
"fmt"
"time"
"github.com/alicebob/miniredis/v2"
"github.com/rahmadafandi/fibr/v2/rediskit"
goredis "github.com/redis/go-redis/v9"
)
func main() {
mr, _ := miniredis.Run()
defer mr.Close()
client := goredis.NewClient(&goredis.Options{Addr: mr.Addr()})
store := rediskit.NewStorage(client, rediskit.WithPrefix("ratelimit:"))
_ = store.Set("1.2.3.4", []byte("1"), time.Minute)
v, _ := store.Get("1.2.3.4")
fmt.Println(string(v))
}
Output: 1
func (*Storage) Close ¶
Close closes the underlying go-redis client. Call it only if this Storage owns the client; do not close a client shared with other consumers here.
func (*Storage) DeleteWithContext ¶
DeleteWithContext is Delete bounded by ctx.
func (*Storage) GetWithContext ¶
GetWithContext is Get bounded by ctx.
func (*Storage) Reset ¶
Reset deletes every key under the prefix (not the whole database). It deletes in batches so a large key space does not build one giant DEL.
func (*Storage) ResetWithContext ¶
ResetWithContext is Reset bounded by ctx.
type StorageOption ¶
type StorageOption func(*Storage)
StorageOption configures a Storage.
func WithPrefix ¶
func WithPrefix(prefix string) StorageOption
WithPrefix sets the key namespace (default "fiber:storage:").
type Subscription ¶
type Subscription struct {
// contains filtered or unexported fields
}
Subscription is an active subscription. Close stops the background goroutine and unsubscribes.
func Subscribe ¶
func Subscribe[T any](ctx context.Context, r *Redis, channel string, handler func(context.Context, T) error) (*Subscription, error)
Subscribe subscribes to channel and invokes handler for each message (payload JSON-decoded into T) in a background goroutine, until ctx is cancelled or the returned Subscription is closed. Decode and handler errors are logged; a bad message is skipped without ending the subscription.
Example ¶
Publish an event on one instance; every instance subscribed to the channel runs its handler with the decoded payload (e.g. to bust a local cache).
package main
import (
"context"
"github.com/rahmadafandi/fibr/v2/rediskit"
goredis "github.com/redis/go-redis/v9"
)
func main() {
r := rediskit.New(goredis.NewClient(&goredis.Options{Addr: "localhost:6379"}))
ctx := context.Background()
type invalidate struct {
Key string `json:"key"`
}
sub, err := rediskit.Subscribe[invalidate](ctx, r, "cache:invalidate", func(_ context.Context, e invalidate) error {
// drop e.Key from a local cache here
return nil
})
if err != nil {
return
}
defer sub.Close()
_ = r.Publish(ctx, "cache:invalidate", invalidate{Key: "user:1"})
}
Output:
func (*Subscription) Close ¶
func (s *Subscription) Close() error
Close stops the subscription and releases its connection.