cache

package module
v9.0.2 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2023 License: BSD-2-Clause Imports: 12 Imported by: 0

README

Redis cache library for Golang

Build Status GoDoc

go-redis/cache is brought to you by ⭐ uptrace/uptrace. Uptrace is an open source and blazingly fast distributed tracing tool powered by OpenTelemetry and ClickHouse. Give it a star as well!

go-redis/cache library implements a cache using Redis as a key/value storage. It uses MessagePack to marshal values.

Optionally, you can use TinyLFU or any other cache algorithm as a local in-process cache.

If you are interested in monitoring cache hit rate, see the guide for Monitoring using OpenTelemetry Metrics.

Installation

go-redis/cache supports 2 last Go versions and requires a Go version with modules support. So make sure to initialize a Go module:

go mod init github.com/my/repo

And then install go-redis/cache/v9 (note v9 in the import; omitting it is a popular mistake):

go get github.com/flemeur/redis-cache/v9

Quickstart

package cache_test

import (
    "context"
    "fmt"
    "time"

    "github.com/redis/go-redis/v9"
    "github.com/flemeur/redis-cache/v9"
)

type Object struct {
    Str string
    Num int
}

func Example_basicUsage() {
    ring := redis.NewRing(&redis.RingOptions{
        Addrs: map[string]string{
            "server1": ":6379",
            "server2": ":6380",
        },
    })

    mycache := cache.New(&cache.Options{
        Redis:      ring,
        LocalCache: cache.NewTinyLFU(1000, time.Minute),
    })

    ctx := context.TODO()
    key := "mykey"
    obj := &Object{
        Str: "mystring",
        Num: 42,
    }

    if err := mycache.Set(&cache.Item{
        Ctx:   ctx,
        Key:   key,
        Value: obj,
        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}
}

func Example_advancedUsage() {
    ring := redis.NewRing(&redis.RingOptions{
        Addrs: map[string]string{
            "server1": ":6379",
            "server2": ":6380",
        },
    })

    mycache := cache.New(&cache.Options{
        Redis:      ring,
        LocalCache: cache.NewTinyLFU(1000, time.Minute),
    })

    obj := new(Object)
    err := mycache.Once(&cache.Item{
        Key:   "mykey",
        Value: obj, // destination
        Do: func(*cache.Item) (interface{}, error) {
            return &Object{
                Str: "mystring",
                Num: 42,
            }, nil
        },
    })
    if err != nil {
        panic(err)
    }
    fmt.Println(obj)
    // Output: &{mystring 42}
}

Documentation

Overview

Example (AdvancedUsage)
ring := redis.NewRing(&redis.RingOptions{
	Addrs: map[string]string{
		"server1": ":6379",
		"server2": ":6380",
	},
})

mycache := cache.New(&cache.Options{
	Redis:      ring,
	LocalCache: cache.NewTinyLFU(1000, time.Minute),
})

obj := new(Object)
err := mycache.Once(&cache.Item{
	Key:   "mykey",
	Value: obj, // destination
	Do: func(*cache.Item) (interface{}, error) {
		return &Object{
			Str: "mystring",
			Num: 42,
		}, nil
	},
})
if err != nil {
	panic(err)
}
fmt.Println(obj)
Output:

&{mystring 42}
Example (BasicUsage)
ring := redis.NewRing(&redis.RingOptions{
	Addrs: map[string]string{
		"server1": ":6379",
		"server2": ":6380",
	},
})

mycache := cache.New(&cache.Options{
	Redis:      ring,
	LocalCache: cache.NewTinyLFU(1000, time.Minute),
})

ctx := context.TODO()
key := "mykey"
obj := &Object{
	Str: "mystring",
	Num: 42,
}

if err := mycache.Set(&cache.Item{
	Ctx:   ctx,
	Key:   key,
	Value: obj,
	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}

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrCacheMiss = errors.New("cache: key is missing")
)

Functions

This section is empty.

Types

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

func New

func New(opt *Options) *Cache

func (*Cache) Delete

func (cd *Cache) Delete(ctx context.Context, key string) error

func (*Cache) DeleteFromLocalCache

func (cd *Cache) DeleteFromLocalCache(key string)

func (*Cache) Exists

func (cd *Cache) Exists(ctx context.Context, key string) bool

Exists reports whether value for the given key exists.

func (*Cache) Get

func (cd *Cache) Get(ctx context.Context, key string, value interface{}) error

Get gets the value for the given key.

func (*Cache) GetSkippingLocalCache

func (cd *Cache) GetSkippingLocalCache(
	ctx context.Context, key string, value interface{},
) error

Get gets the value for the given key skipping local cache.

func (*Cache) Marshal

func (cd *Cache) Marshal(value interface{}) ([]byte, error)

func (*Cache) Once

func (cd *Cache) Once(item *Item) error

Once gets the item.Value for the given item.Key from the cache or executes, caches, and returns the results of the given item.Func, making sure that only one execution is in-flight for a given item.Key at a time. If a duplicate comes in, the duplicate caller waits for the original to complete and receives the same results.

func (*Cache) Set

func (cd *Cache) Set(item *Item) error

Set caches the item.

func (*Cache) Stats

func (cd *Cache) Stats() *Stats

Stats returns cache statistics.

func (*Cache) Unmarshal

func (cd *Cache) Unmarshal(b []byte, value interface{}) error

type Item

type Item struct {
	Ctx context.Context

	Key   string
	Value interface{}

	// TTL is the cache expiration time.
	// Default TTL is 0 = cache forever.
	// 0 or negative means cache forever.
	// TTL durations must be at least 1 * time.Second, otherwise it will be set to 1 * time.Second.
	TTL time.Duration

	// Do returns value to be cached.
	Do func(*Item) (interface{}, error)

	// SetXX only sets the key if it already exists.
	SetXX bool

	// SetNX only sets the key if it does not already exist.
	SetNX bool

	// SkipLocalCache skips local cache as if it is not set.
	SkipLocalCache bool
}

func (*Item) Context

func (item *Item) Context() context.Context

type LocalCache

type LocalCache interface {
	Set(key string, data []byte)
	Get(key string) ([]byte, bool)
	Del(key string)
}

type MarshalFunc

type MarshalFunc func(interface{}) ([]byte, error)

------------------------------------------------------------------------------

type Options

type Options struct {
	Redis        rediser
	LocalCache   LocalCache
	StatsEnabled bool
	Marshal      MarshalFunc
	Unmarshal    UnmarshalFunc
}

type Stats

type Stats struct {
	Hits   uint64
	Misses uint64
}

type TinyLFU

type TinyLFU struct {
	// contains filtered or unexported fields
}

func NewTinyLFU

func NewTinyLFU(size int, ttl time.Duration) *TinyLFU

func (*TinyLFU) Del

func (c *TinyLFU) Del(key string)

func (*TinyLFU) Get

func (c *TinyLFU) Get(key string) ([]byte, bool)

func (*TinyLFU) Set

func (c *TinyLFU) Set(key string, b []byte)

func (*TinyLFU) UseRandomizedTTL

func (c *TinyLFU) UseRandomizedTTL(offset time.Duration)

type UnmarshalFunc

type UnmarshalFunc func([]byte, interface{}) error

------------------------------------------------------------------------------

Jump to

Keyboard shortcuts

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