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 WithSeparator(separator string) Option
- func WithSeparatorDisabled(separatorDisabled bool) 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
- func (w *T[K, V]) Delete(ctx context.Context, key string, id K) error
- func (w *T[K, V]) Exists(ctx context.Context, key string, id K) bool
- func (w *T[K, V]) Get(ctx context.Context, key string, id K, fn func(context.Context, K) (V, error)) (V, error)
- func (w *T[K, V]) MGet(ctx context.Context, key string, ids []K, ...) (result map[K]V)
- func (w *T[K, V]) MGetWithErr(ctx context.Context, key string, ids []K, ...) (result map[K]V, errs error)
- func (w *T[K, V]) Set(ctx context.Context, key string, id K, v V) error
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 ¶ added in v1.1.1
func WithEventHandler ¶ added in v1.1.1
func WithNotFoundExpiry ¶
func WithOffset ¶
func WithRefreshConcurrency ¶
func WithRefreshDuration ¶
func WithRemote ¶
func WithRemoteExpiry ¶
func WithSeparator ¶ added in v1.2.0
func WithSeparatorDisabled ¶ added in v1.2.1
func WithSourceId ¶ added in v1.1.1
func WithStatsDisabled ¶
func WithStatsHandler ¶
func WithSyncLocal ¶ added in v1.1.1
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]) Exists ¶ added in v1.2.6
Exists reports whether val for the given `key` and `id` exists.
func (*T[K, V]) Get ¶ added in v1.1.4
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 is a wrapper around MGetWithErr that logs any errors and returns only the results.
func (*T[K, V]) MGetWithErr ¶ added in v1.2.4
func (w *T[K, V]) MGetWithErr(ctx context.Context, key string, ids []K, fn func(context.Context, []K) (map[K]V, error)) (result map[K]V, errs error)
MGetWithErr efficiently retrieves multiple values associated with the given `key` and `ids`, returning both the results and any errors encountered during the process.
It first attempts to retrieve values from the local cache (if enabled), then from the remote cache (if enabled). For any values not found in the caches, it calls the provided `fn` function to fetch them from the underlying data source. The fetched values are then stored in both the local and remote caches for future use.
The results are returned as a map where the key is the `id` and the value is the corresponding data. Any errors encountered during the cache retrieval or data fetching process are returned as a non-nil error.