Mise en cache Encore Go (Redis)
Instructions
Le cache d'Encore Go est un wrapper typé autour de Redis. Déclarez un cache.Cluster une seule fois, puis créez des objets Keyspace pour chaque forme de données dont vous avez besoin.
Cluster
package mycache
import "encore.dev/storage/cache"
var Cluster = cache.NewCluster("my-cache", cache.ClusterConfig{
EvictionPolicy: cache.AllKeysLRU,
})
Politiques d'éviction : cache.AllKeysLRU (par défaut), cache.NoEviction, cache.AllKeysLFU, cache.AllKeysRandom, cache.VolatileLRU, cache.VolatileLFU, cache.VolatileTTL, cache.VolatileRandom.
Types de keyspace
Chaque keyspace a une forme de clé (utilisée pour construire la clé Redis à partir de KeyPattern) et un type de valeur.
package mycache
import (
"context"
"time"
"encore.dev/storage/cache"
)
type TokenKey struct {
TokenID string
}
// Strings
var Tokens = cache.NewStringKeyspace[TokenKey](Cluster, cache.KeyspaceConfig{
KeyPattern: "token/:TokenID",
DefaultExpiry: cache.ExpireIn(time.Hour),
})
func example(ctx context.Context) {
_ = Tokens.Set(ctx, TokenKey{TokenID: "abc"}, "value")
val, err := Tokens.Get(ctx, TokenKey{TokenID: "abc"}) // cache.Miss on miss
_ = Tokens.Delete(ctx, TokenKey{TokenID: "abc"})
_ = val
_ = err
}
// Integers (atomic counters)
type CounterKey struct {
UserID string
}
var Counters = cache.NewIntKeyspace[CounterKey](Cluster, cache.KeyspaceConfig{
KeyPattern: "requests/:UserID",
DefaultExpiry: cache.ExpireIn(10 * time.Second),
})
func incr(ctx context.Context) {
count, _ := Counters.Increment(ctx, CounterKey{UserID: "user123"}, 1)
_, _ = Counters.Decrement(ctx, CounterKey{UserID: "user123"}, 1)
_ = count
}
// Structs (JSON-encoded)
type ProfileKey struct {
UserID string
}
type UserProfile struct {
Name string
Email string
}
var Profiles = cache.NewStructKeyspace[ProfileKey, UserProfile](Cluster, cache.KeyspaceConfig{
KeyPattern: "profile/:UserID",
DefaultExpiry: cache.ExpireIn(time.Hour),
})
func setProfile(ctx context.Context) {
_ = Profiles.Set(ctx, ProfileKey{UserID: "123"}, UserProfile{
Name: "Alice", Email: "alice@example.com",
})
}
Autres types de keyspace
Tous depuis encore.dev/storage/cache :
NewFloatKeyspace— valeurs float64, avecIncrement.NewListKeyspace— valeurs de liste, avecPushLeft/PushRight/PopLeft/PopRight/GetRange.NewSetKeyspace— valeurs d'ensemble, avecAdd/Remove/Contains/Items.
Motifs de clés multi-champs
type ResourceKey struct {
UserID string
ResourcePath string
}
var ResourceRequests = cache.NewIntKeyspace[ResourceKey](Cluster, cache.KeyspaceConfig{
KeyPattern: "requests/:UserID/:ResourcePath",
DefaultExpiry: cache.ExpireIn(10 * time.Second),
})
Helpers d'expiration
import (
"encore.dev/storage/cache"
"time"
)
cache.ExpireIn(time.Hour) // relative
cache.ExpireDailyAt(2, 0, 0, time.UTC) // heure UTC spécifique chaque jour
cache.NeverExpire // pas d'expiration
cache.KeepTTL // conserver le TTL existant lors de la mise à jour
Erreurs
import "encore.dev/storage/cache"
val, err := keyspace.Get(ctx, key)
if errors.Is(err, cache.Miss) {
// pas en cache
}
err = keyspace.SetIfNotExists(ctx, key, value)
if errors.Is(err, cache.KeyExists) {
// déjà présent
}
Recommandations
- Déclarez
cache.Clusteret les keyspaces comme variables au niveau du package. - Choisissez le type de keyspace le plus spécifique —
IntKeyspacepour les compteurs vous donneIncrement/Decrementatomiques gratuitement. Get()retournecache.Missen cas d'absence ;Replace()etSetIfNotExists()retournentcache.Miss/cache.KeyExistsen cas de conflit.- Le développement local utilise un Redis en mémoire avec un plafond d'environ 100 clés — ne le testez pas en charge.
- Pour le stockage durable, utilisez
encore-go-database(Postgres) ouencore-go-bucket(stockage d'objets) à la place.