relevantcache

package module
v0.12.2 Latest Latest
Warning

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

Go to latest
Published: Dec 17, 2020 License: MIT Imports: 11 Imported by: 0

README

relevantcache

relevantcache manages caches with relevant to other cache keys.

Installtion

$ go get -u github.com/ysugimoto/relevantcache

Usage

Simple KVS

Typical usage of simple KVS store:

import (
    "log"

    rc "github.com/ysugimoto/relevantcache"
)

func main() {
    c, err := rc.NewRedis("redis://127.0.0.1:6379")
    if err != nil {
        log.Fatalln(err)
    }

    if err := c.Set("lorem", "ipsum"); err != nil {
        log.Fatalln(err)
    }
    v, err := c.Get("lorem")
    if err != nil {
        log.Fatalln(err)
    }
    log.Println(string(v)) // -> "ipsum"
}

Note that on simple usage, we always return value as []byte.

Relevant KVS

Use rc.Item instead of primitive value:

import (
    "log"

    rc "github.com/ysugimoto/relevantcache"
)

func main() {
    c, err := rc.NewRedis("redis://127.0.0.1:6379")
    if err != nil {
        log.Fatalln(err)
    }

    // some existing cache
    if err := c.Set("parent01", "foo"); err != nil {
        log.Fatalln(err)
    }
    // use relevant cache
    item := rc.NewItem("child01").RelevantTo("parent01").Value("bar")
    if err := c.Set(item); err != nil {
        log.Fatalln(err)
    }

    // And delete it
    err := c.Del("child01")
    if err != nil {
        log.Fatalln(err)
    }

    // "parent01" also deleted.
}

Describe how it works

This package uses a first of N bytes in cache record as relevant cache metadata, the record format is:

[key]: ![relevant cache keys as comma contanetion data]@[split keys (currently no use)]@[cache data...]

The first character of ! indicates (record has a metadata), and following, relevant cache keys, and split keys can be seen with delimiter @.

GET

We retrieve a cache from backend and strip metadata, and return original record. You don't need to care about metadata.

SET

We make a metadata section and prepend to cache record with some signature which distinguish that is metadata.

DEL

We retrieve a cache from backend and parse metadata, and delete them as cache key recursibely.

TLS Connection

When you connect to redis with secure TLS, you can specify endpoint URL that starts with tls://:

c, err := rc.NewRedis("tls://127.0.0.1:6380")

Features

  • Redis Backend
  • Memcached Backend

License

MIT

Author

Yoshiaki Sugimoto

Documentation

Overview

relevantcache package manages "relevant" cache keys in some cache backend (now redis).

Describe:

Occasionally some of caches have relevant like:

cacheA -> cacheB -> cacheC ...

When cacheA has been destroyed, we also delete cacheB because they are relevant. And, when cacheB has been destroyed, cacheC will be destroyed.

Strategy:

Just simple. we prepend metadata that is relevant cache keys when store a cache data. When we get it, retrieve metadata and return cache data only, and when we delete it, extract metadata, factory relevant keys recursively, and delete those.

Index

Constants

This section is empty.

Variables

View Source
var RedisNil = redis.Nil

Functions

func KeyGen

func KeyGen(args ...interface{}) string

func WithDebugWriter

func WithDebugWriter(w io.Writer) option

func WithSkipTLSVerify

func WithSkipTLSVerify(skip bool) option

Types

type Cache

type Cache interface {
	Get(item interface{}) ([]byte, error)
	Set(args ...interface{}) error
	Del(items ...interface{}) error
	Unlink(items ...interface{}) error
	Increment(key string) error
	Close() error
	Dump() string
	Purge() error
	MGet(keys ...interface{}) ([][]byte, error)
	HSet(key interface{}, field string, value interface{}) error
	HLen(key interface{}) (int64, error)
	HGet(key interface{}, field string) ([]byte, error)
	Redis() *redis.Client // should return *redis.Client if you are using *RedisCache otherwise nil
}

All methods accepts as interface{} because argument can be passed as string or *Item

type Item

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

Relevant item struct If you have relevant keys, create pointer of this struct and pass to methods

func NewItem

func NewItem(args ...interface{}) *Item

Crate Item pointer. argment accepts any amounts, types. Arguments becomes cache key.

func (*Item) RelevantAll

func (i *Item) RelevantAll(args ...interface{}) *Item

Declare relevant cache keys with asterisk sign suffix

func (*Item) RelevantTo

func (i *Item) RelevantTo(args ...interface{}) *Item

Declare relevant cache keys

func (*Item) Ttl

func (i *Item) Ttl(ttl int64) *Item

Set TTL

func (*Item) Value

func (i *Item) Value(val interface{}) *Item

Set Value

type MemoryCache

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

func NewMemoryCache

func NewMemoryCache(opts ...option) *MemoryCache

func (*MemoryCache) Close

func (m *MemoryCache) Close() error

func (*MemoryCache) Del

func (m *MemoryCache) Del(items ...interface{}) error

func (*MemoryCache) Dump

func (m *MemoryCache) Dump() string

func (*MemoryCache) Get

func (m *MemoryCache) Get(item interface{}) ([]byte, error)

func (*MemoryCache) HGet added in v0.12.0

func (m *MemoryCache) HGet(key interface{}, field string) ([]byte, error)

func (*MemoryCache) HLen added in v0.12.0

func (m *MemoryCache) HLen(key interface{}) (int64, error)

func (*MemoryCache) HSet added in v0.12.0

func (m *MemoryCache) HSet(key interface{}, field string, value interface{}) error

func (*MemoryCache) Increment

func (m *MemoryCache) Increment(key string) error

func (*MemoryCache) MGet added in v0.11.0

func (m *MemoryCache) MGet(keys ...interface{}) ([][]byte, error)

func (*MemoryCache) Purge

func (m *MemoryCache) Purge() error

func (*MemoryCache) Redis added in v0.12.1

func (m *MemoryCache) Redis() *redis.Client

func (*MemoryCache) Set

func (m *MemoryCache) Set(args ...interface{}) (err error)
func (m *MemoryCache) Unlink(keys ...interface{}) error

type RedisCache

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

Redis backend struct

func NewRedisCache

func NewRedisCache(endpoint string, opts ...option) (*RedisCache, error)

Create RedisCache pointer with some options Currently enabled options are:

rc.WithSkipTLSVerify(bool): Skip TLS verification

func (*RedisCache) Close

func (r *RedisCache) Close() error

Close connection

func (*RedisCache) Del

func (r *RedisCache) Del(items ...interface{}) error

Wrap of redis.DEL item is acceptable either of string of *Item

func (*RedisCache) Dump

func (r *RedisCache) Dump() string

func (*RedisCache) Get

func (r *RedisCache) Get(item interface{}) ([]byte, error)

Wrap of redis.GET item is acceptable either of string of *Item

func (*RedisCache) HGet added in v0.12.0

func (r *RedisCache) HGet(key interface{}, field string) ([]byte, error)

func (*RedisCache) HLen added in v0.12.0

func (r *RedisCache) HLen(key interface{}) (int64, error)

func (*RedisCache) HSet added in v0.12.0

func (r *RedisCache) HSet(key interface{}, field string, value interface{}) error

func (*RedisCache) Increment

func (r *RedisCache) Increment(key string) error

func (*RedisCache) MGet added in v0.11.0

func (r *RedisCache) MGet(keys ...interface{}) ([][]byte, error)

func (*RedisCache) Purge

func (r *RedisCache) Purge() error

Purge all caches

func (*RedisCache) Redis added in v0.12.1

func (r *RedisCache) Redis() *redis.Client

func (*RedisCache) Set

func (r *RedisCache) Set(args ...interface{}) (err error)

Wrap of redis.SET/redis.SETEX args is acceptable with following argument counts:

count is 1: deal with *Item count is 2: deal with first argument as cache key, second argument as value. TTL is 0 (no expiration) count is 3: deal with first argument as cache key, second argument as value, third argument as TTL

func (r *RedisCache) Unlink(items ...interface{}) error

Wrap of redis.UNLINK, note that ensure your redis engine is later than v4 item is acceptable either of string of *Item

Jump to

Keyboard shortcuts

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