Documentation ¶
Overview ¶
Example (AdvancedUsage) ¶
ring := redis.NewRing(&redis.RingOptions{ Addrs: map[string]string{ "localhost": ":6379", }, }) mycache := cache.New(cache.WithName("any"), cache.WithRemote(remote.NewGoRedisV9Adapter(ring)), cache.WithLocal(local.NewFreeCache(256*local.MB, time.Minute)), cache.WithErrNotFound(errRecordNotFound), cache.WithRefreshDuration(time.Minute)) ctx := context.TODO() key := "mykey:1" obj := new(object) if err := mycache.Once(ctx, key, cache.Value(obj), cache.TTL(time.Hour), cache.Refresh(true), cache.Do(func(ctx context.Context) (any, error) { return mockDBGetObject(1) })); err != nil { panic(err) } fmt.Println(obj)
Output: &{mystring 42}
Example (BasicUsage) ¶
ring := redis.NewRing(&redis.RingOptions{ Addrs: map[string]string{ "localhost": ":6379", }, }) mycache := cache.New(cache.WithName("any"), cache.WithRemote(remote.NewGoRedisV9Adapter(ring)), cache.WithLocal(local.NewFreeCache(256*local.MB, time.Minute)), cache.WithErrNotFound(errRecordNotFound)) ctx := context.TODO() key := "mykey:1" obj, _ := mockDBGetObject(1) if err := mycache.Set(ctx, key, cache.Value(obj), cache.TTL(time.Hour)); err != nil { panic(err) } var wanted object if err := mycache.Get(ctx, key, &wanted); err == nil { fmt.Println(wanted) }
Output: {mystring 42}
Example (MGetUsage) ¶
ring := redis.NewRing(&redis.RingOptions{ Addrs: map[string]string{ "localhost": ":6379", }, }) mycache := cache.New(cache.WithName("any"), cache.WithRemote(remote.NewGoRedisV9Adapter(ring)), cache.WithLocal(local.NewFreeCache(256*local.MB, time.Minute)), cache.WithErrNotFound(errRecordNotFound), cache.WithRemoteExpiry(time.Minute), ) cacheT := cache.NewT[int, *object](mycache) ctx := context.TODO() key := "mget" ids := []int{1, 2, 3} ret := cacheT.MGet(ctx, key, ids, func(ctx context.Context, ids []int) (map[int]*object, error) { return mockDBMGetObject(ids) }) var b bytes.Buffer for _, id := range ids { b.WriteString(fmt.Sprintf("%v", ret[id])) } fmt.Println(b.String())
Output: &{mystring 1}&{mystring 2}<nil>
Example (SyncLocalUsage) ¶
ring := redis.NewRing(&redis.RingOptions{ Addrs: map[string]string{ "localhost": ":6379", }, }) sourceID := "12345678" // Unique identifier for this cache instance channelName := "syncLocalChannel" pubSub := ring.Subscribe(context.Background(), channelName) mycache := cache.New(cache.WithName("any"), cache.WithRemote(remote.NewGoRedisV9Adapter(ring)), cache.WithLocal(local.NewFreeCache(256*local.MB, time.Minute)), cache.WithErrNotFound(errRecordNotFound), cache.WithRemoteExpiry(time.Minute), cache.WithSourceId(sourceID), cache.WithSyncLocal(true), cache.WithEventHandler(func(event *cache.Event) { // Broadcast local cache invalidation for the received keys bs, _ := json.Marshal(event) ring.Publish(context.Background(), channelName, string(bs)) }), ) obj, _ := mockDBGetObject(1) if err := mycache.Set(context.TODO(), "mykey", cache.Value(obj), cache.TTL(time.Hour)); err != nil { panic(err) } go func() { for { msg := <-pubSub.Channel() var event *cache.Event if err := json.Unmarshal([]byte(msg.Payload), &event); err != nil { panic(err) } fmt.Println(event.Keys) // Invalidate local cache for received keys (except own events) if event.SourceID != sourceID { for _, key := range event.Keys { mycache.DeleteFromLocalCache(key) } } } }()
Output: [mykey]
Index ¶
- Constants
- Variables
- type Cache
- type DoFunc
- type Event
- type EventType
- type ItemOption
- type Option
- func WithCodec(codec string) Option
- func WithErrNotFound(err error) Option
- func WithEventChBufSize(eventChBufSize int) Option
- func WithEventHandler(eventHandler func(event *Event)) Option
- func WithLocal(local local.Local) Option
- func WithName(name string) Option
- func WithNotFoundExpiry(notFoundExpiry time.Duration) Option
- func WithOffset(offset time.Duration) Option
- func WithRefreshConcurrency(refreshConcurrency int) Option
- func WithRefreshDuration(refreshDuration time.Duration) Option
- func WithRemote(remote remote.Remote) Option
- func WithRemoteExpiry(remoteExpiry time.Duration) Option
- func WithSourceId(sourceId string) Option
- func WithStatsDisabled(statsDisabled bool) Option
- func WithStatsHandler(handler stats.Handler) Option
- func WithStopRefreshAfterLastAccess(stopRefreshAfterLastAccess time.Duration) Option
- func WithSyncLocal(syncLocal bool) Option
- type Options
- type T
Examples ¶
Constants ¶
const ( TypeLocal = "local" TypeRemote = "remote" TypeBoth = "both" )
Variables ¶
var ( ErrCacheMiss = errors.New("cache: key is missing") ErrRemoteLocalBothNil = errors.New("cache: both remote and local are nil") )
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache interface { // Set sets the cache with ItemOption Set(ctx context.Context, key string, opts ...ItemOption) error // Once gets the opts.value for the given key from the cache or // executes, caches, and returns the results of the given opts.do, // making sure that only one execution is in-flight for a given key // at a time. If a duplicate comes in, the duplicate caller waits for the // original to complete and receives the same results. Once(ctx context.Context, key string, opts ...ItemOption) error // Delete deletes cached val with key. Delete(ctx context.Context, key string) error // DeleteFromLocalCache deletes local cached val with key. DeleteFromLocalCache(key string) // Exists reports whether val for the given key exists. Exists(ctx context.Context, key string) bool // Get gets the val for the given key and fills into val. Get(ctx context.Context, key string, val any) error // GetSkippingLocal gets the val for the given key skipping local cache. GetSkippingLocal(ctx context.Context, key string, val any) error // TaskSize returns Refresh task size. TaskSize() int // CacheType returns cache type CacheType() string // Close closes the cache. This should be called when cache refreshing is // enabled and no longer needed, or when it may lead to resource leaks. Close() }
Cache interface is used to define the cache implementation.
type ItemOption ¶
type ItemOption func(o *item)
ItemOption defines the method to customize an Options.
func Do ¶
func Do(do DoFunc) ItemOption
func Refresh ¶
func Refresh(refresh bool) ItemOption
func SetNX ¶
func SetNX(setNx bool) ItemOption
func SetXX ¶
func SetXX(setXx bool) ItemOption
func SkipLocal ¶
func SkipLocal(skipLocal bool) ItemOption
func TTL ¶
func TTL(ttl time.Duration) ItemOption
func Value ¶
func Value(value any) ItemOption
type Option ¶
type Option func(o *Options)
Option defines the method to customize an Options.
func WithErrNotFound ¶
func WithEventChBufSize ¶
func WithEventHandler ¶
func WithNotFoundExpiry ¶
func WithOffset ¶
func WithRefreshConcurrency ¶
func WithRefreshDuration ¶
func WithRemote ¶
func WithRemoteExpiry ¶
func WithSourceId ¶
func WithStatsDisabled ¶
func WithStatsHandler ¶
func WithSyncLocal ¶
type Options ¶
type Options struct {
// contains filtered or unexported fields
}
Options are used to store cache options.
type T ¶
type T[K constraints.Ordered, V any] struct { Cache }
T wrap Cache to support golang's generics
func (*T[K, V]) Get ¶
func (w *T[K, V]) Get(ctx context.Context, key string, id K, fn func(context.Context, K) (V, error)) (V, error)
Get retrieves the value associated with the given `key` and `id`.
It first attempts to fetch the value from the cache. If a cache miss occurs, it calls the provided `fn` function to fetch the value and stores it in the cache with an expiration time determined by the cache configuration.
A `Once` mechanism is employed to ensure only one fetch is performed for a given `key` and `id` combination, even under concurrent access.
func (*T[K, V]) MGet ¶
func (w *T[K, V]) MGet(ctx context.Context, key string, ids []K, fn func(context.Context, []K) (map[K]V, error)) (result map[K]V)
MGet efficiently retrieves multiple values associated with the given `key` and `ids`.
It attempts to fetch all values from the cache. For missing values, it calls the provided `fn` function to fetch the remaining values and updates the cache with an expiration time determined by the cache configuration.
The results are returned as a map where the key is the `id` and the value is the corresponding data.