gocache

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2024 License: MIT Imports: 11 Imported by: 0

README

gocache

golang loadable cache 中文说明

Features

  • ✅ Multiple built-in caches that can be used individually or in combination
  • ✅ Use generics to avoid duplicate code and be type safe.
  • ✅ Drawing on the strengths of gocache and go-zero cache designs.
  • ✅ Breakthrough proof: singleflight design ensures that only one request accesses the backend
  • ✅ Avalanche-proof: cache expiration time is randomized to avoid a large number of cache failures at the same time
  • ✅ Configurable: customizable cache key, cache configuration parameters can be modified
  • ✅ Stable and reliable: already used in production environments

Built-in cache

Installation

go get github.com/nzai/gocache

Usage

Use in-memory cache
import (
    "context"
    "time"

    "github.com/nzai/gocache"
)

func main() {
    ctx := context.Background()
    mc := gocache.NewMemoryCache[string](10 * time.Second)
    err := mc.Set(ctx, "key1", "v1")
    if err ! = nil {
        log.Fatalf("failed to set cache value due to %v", err)
    }

    got, err := mc.Get(ctx, "key1")
    Get(ctx, "key1") if err ! = nil {
        log.Fatalf("failed to get cache value due to %v", err)
    }

    log.Printf("got cached value %s", got)
}
in-memory caching objects
type User struct {
    ID string
    Name string
}

mc := gocache.NewMemoryCache[*User](30 * time.Second)
Use Redis cache
import (
    "github.com/nzai/gocache"
    "github.com/redis/go-redis/v9"
)

client := redis.NewClient(&redis.Options{
    Addr: "127.0.0.1:6379",
})

rc := gocache.NewRedisCache[*User](client, 30 * time.Second)
Use ChainCache
import (
    "github.com/nzai/gocache"
    "github.com/redis/go-redis/v9"
)

client := redis.NewClient(&redis.Options{
    Addr: "127.0.0.1:6379",
})

mc := gocache.NewMemoryCache[string](10 * time.Second)
rc := gocache.NewRedisCache[string](client, 30 * time.Second)
cc := gocache.NewChainCache[string](mc, rc)
Use LoadableCache
import (
    "github.com/nzai/gocache"
)

type Request struct {
    ID string
}

type Response struct {
    Name string
    Value string
}

func GetValue(request *Request) (*Response, error) {
    return &Response{Name:"n1", Value:"v1"}
}

mc := gocache.NewMemoryCache[*Response*](10 * time.Minute)
lc := gocache.NewLoadableCache[*Request*, *Response](mc)

request := &Request{ID: "id1"}
response, err := lc.Load(GetValue, request)
if err != nil {
    log.Fatalf("failed to get value from cache due to %v", err)
}
Use LoadableL2Cache
import (
    "github.com/nzai/gocache"
)

type Request struct {
    ID string
}

type Response struct {
    Name string
    Value string
}

func GetValue(request *Request) (*Response, error) {
    return &Response{Name:"n1", Value:"v1"}
}

client := redis.NewClient(&redis.Options{
    Addr: "127.0.0.1:6379",
})

lc := gocache.NewLoadableL2Cache[*Request*, *Response](client, 1*time.Minute)

ctx := context.Background()
request := &Request{ID: "id1"}
response, err := lc.LoadCtx(ctx, GetValue, request)
if err != nil {
    log.Fatalf("failed to get value from cache due to %v", err)
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// it can be changed and default value is 0.05
	ExpiryDeviation = 0.05

	ErrRecordNotFound = errors.New("record not found")
)
View Source
var (
	// it can be changed and default value is 0.25
	DecayFactor = 0.25
)

Functions

func GenerateCacheKey

func GenerateCacheKey(arg any) string

GenerateCacheKey returns the cache key for the given key object by returning the key if type is string or by computing a checksum of key structure if its type is other than string

Types

type Cache

type Cache[T any] interface {
	Set(ctx context.Context, key string, value T) error
	Get(ctx context.Context, key string) (T, error)
}

type CacheConfig

type CacheConfig struct {
	// key prefix
	Prefix string
}

type CacheKeyGenerator

type CacheKeyGenerator interface {
	GetCacheKey() string
}

type CacheOption

type CacheOption func(*CacheConfig)

func WithKeyPrefix

func WithKeyPrefix(prefix string) CacheOption

type ChainCache

type ChainCache[T any] struct {
	// contains filtered or unexported fields
}

func NewChainCache

func NewChainCache[T any](caches ...Cache[T]) *ChainCache[T]

NewChainCache instanciates a new cache that combine other caches

func (ChainCache[T]) Get

func (c ChainCache[T]) Get(ctx context.Context, key string) (value T, err error)

func (ChainCache[T]) Set

func (c ChainCache[T]) Set(ctx context.Context, key string, value T) error

type ChainCacheValue

type ChainCacheValue[T any] struct {
	Caches []Cache[T]
	Key    string
	Value  T
}

type LoadFunction

type LoadFunction[T, K any] func(T) (K, error)

type LoadFunctionCtx

type LoadFunctionCtx[T, K any] func(context.Context, T) (K, error)

type LoadableCache

type LoadableCache[T, K any] struct {
	// contains filtered or unexported fields
}

func NewLoadableCache

func NewLoadableCache[T, K any](cache Cache[K]) *LoadableCache[T, K]

NewLoadableCache instanciates a new cache that uses a function to load data

func (*LoadableCache[T, K]) Load

func (c *LoadableCache[T, K]) Load(fn LoadFunction[T, K], arg T) (K, error)

Load returns the object stored in cache

func (*LoadableCache[T, K]) LoadCtx

func (c *LoadableCache[T, K]) LoadCtx(ctx context.Context, fn LoadFunctionCtx[T, K], arg T) (K, error)

LoadCtx returns the object stored in cache with context

type LoadableL2Cache

type LoadableL2Cache[T, K any] struct {
	*LoadableCache[T, K]
}

func NewLoadableL2Cache

func NewLoadableL2Cache[T, K any](client *redis.Client, expiration time.Duration) *LoadableL2Cache[T, K]

type MemoryCache

type MemoryCache[T any] struct {
	// contains filtered or unexported fields
}

func NewMemoryCache

func NewMemoryCache[T any](expiration time.Duration, options ...CacheOption) *MemoryCache[T]

func (MemoryCache[T]) Delete

func (s MemoryCache[T]) Delete(key string) error

func (MemoryCache[T]) Get

func (s MemoryCache[T]) Get(ctx context.Context, key string) (T, error)

func (*MemoryCache[T]) Set

func (s *MemoryCache[T]) Set(ctx context.Context, key string, value T) error

type RedisCache

type RedisCache[T any] struct {
	// contains filtered or unexported fields
}

func NewRedisCache

func NewRedisCache[T any](client *redis.Client, expiration time.Duration, options ...CacheOption) *RedisCache[T]

func (RedisCache[T]) Get

func (s RedisCache[T]) Get(ctx context.Context, key string) (value T, err error)

func (RedisCache[T]) Set

func (s RedisCache[T]) Set(ctx context.Context, key string, value T) error

type SingleFlight

type SingleFlight[T, K any] interface {
	Do(fn LoadFunction[T, K], arg T) (K, error)
	DoEx(fn LoadFunction[T, K], arg T) (val K, fresh bool, err error)
	DoCtx(ctx context.Context, fn LoadFunctionCtx[T, K], arg T) (K, error)
	DoExCtx(ctx context.Context, fn LoadFunctionCtx[T, K], arg T) (val K, fresh bool, err error)
}

func NewSingleFlight

func NewSingleFlight[T, K any]() SingleFlight[T, K]

NewSingleFlight returns a generic single flight.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL