mc

package module
v0.0.0-...-94a8308 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2024 License: MIT Imports: 16 Imported by: 0

README

Memcache Client

CI Go Report Card godoc

This is a memcache client library for the Go programming language, which uses memcache's binary protocol and supports namespacing out of the box.

Installing

To add this libraty to your project, just run:

go get github.com/kinescope/mc

Example

package main

import (
	"context"
	"log"
	"time"

	"github.com/kinescope/mc"
)

func main() {
	cache, err := mc.New(&mc.Options{
		Addrs:               []string{"127.0.0.1:11211"},
		DialTimeout:         500 * time.Millisecond,
		KeyHashFunc:         mc.XXKeyHashFunc, // or mc.DefaultKeyHashFunc. Hash function to use for namespaces
		ConnMaxLifetime:     15 * time.Minute,
		MaxIdleConnsPerAddr: 20,
	})
	if err != nil {
		log.Fatal(err)
	}

	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second))
	defer cancel()

	type example struct {
		A string
		B string
	}

	var value mc.Value
	err = value.Marshal(example{
		A: "A",
		B: "B",
	})
	if err != nil {
		log.Fatal(err)
	}

	err = cache.Set(ctx, &mc.Item{
		Key:   "cache_key",
		Value: value,
	}, mc.WithExpiration(1_800, 60) /*mc.WithMinUses(10),*/, mc.WithNamespace("my_namespace"))
	if err != nil {
		log.Fatal(err)
	}

	i, err := cache.Get(ctx, "cache_key")
	if err != nil {
		log.Fatal(err)
	}
	var v example
	if err := i.Value.Unmarshal(&v); err != nil {
		log.Fatal(err)
	}
	log.Println(v)
Namespacing

Let's say you have a user with some user_id like 123. Given a user and all his related keys, you want a one-stop switch to invalidate all of their cache entries at the same time. With namespacing you need to add a mc.WithNamespace option when setting any user related key.

// set user name for id
var userName mc.Value
err = userName.Marshal("John")
err = cache.Set(ctx, &mc.Item{
	Key:   "123",
	Value: userName,
}, mc.WithNamespace("user_123"))

// set user email for name
var userEmail mc.Value
err = userEmail.Marshal("example@gmail.com")
err = cache.Set(ctx, &mc.Item{
	Key:   "John",
	Value: userEmail,
}, mc.WithNamespace("user_123"))

Then invalidating all of the keys for a user with id 123 would be as easy as:

cache.PurgeNamespace(ctx, "user_123") // both 123:John and John:example@gmail.com entries will be deleted

Namespaces are hashed by default to prevent collisions. There are two available hash functions - mc.XXKeyHashFunc, witch uses xx-hash, and mc.DefaultKeyHashFunc - witch doesn't hash keys at all.

For more info on namespaces see memcache wiki.

Other options
  • mc.WithExpiration(exp, scale uint32) - after expiration time passes, first request for an item will get a cache miss, any other request will get a hit in a time window of scale seconds. See memcache wiki.
  • mc.WithMinUses(number uint32) - if an item under the key has been set less than number of times, requesting an item will result in a cache miss. See tests for clarity.

Contributing

For contributing see CONTRIBUTING.md

Licensing

The code in this project is licensed under MIT license.

Documentation

Index

Constants

View Source
const (
	DefaultTimeout             = 500 * time.Millisecond
	DefaultConnMaxLifetime     = 30 * time.Minute
	DefaultMaxIdleConnsPerAddr = 10
)
View Source
const MagicValue = 0x42

Variables

View Source
var (
	DefaultKeyHashFunc = func(key string) []byte {
		return str2byte(key)
	}
	XXKeyHashFunc = func(key string) []byte {
		hash := xxHashPool.Get().(*xxhash.Digest)
		hash.Reset()
		hash.WriteString(key)
		sum := hash.Sum(nil)
		{
			xxHashPool.Put(hash)
		}
		return sum
	}
)
View Source
var (
	ErrCacheMiss        = errors.New("memcache: cache miss")
	ErrNotStored        = errors.New("memcache: item not stored")
	ErrNoServers        = errors.New("memcache: no servers configured or available")
	ErrBadIncrDec       = errors.New("memcache: incr or decr on non-numeric value")
	ErrCASConflict      = errors.New("memcache: compare-and-swap conflict")
	ErrServerError      = errors.New("memcache: server error")
	ErrMalformedKey     = errors.New("memcache: key is too long or contains invalid characters")
	ErrAlreadyExists    = errors.New("memcache: item already exists")
	ErrValueTooLarge    = errors.New("memcache: value too large")
	ErrInvalidArguments = errors.New("memcache: invalid arguments")
)

Functions

This section is empty.

Types

type Client

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

func New

func New(o *Options) (_ *Client, err error)

func (*Client) Add

func (c *Client) Add(ctx context.Context, i *Item, o ...Option) error

func (*Client) CompareAndSwap

func (c *Client) CompareAndSwap(ctx context.Context, i *Item, o ...Option) error

func (*Client) Dec

func (c *Client) Dec(ctx context.Context, key string, delta uint64) (uint64, error)

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, key string) error

func (*Client) Get

func (c *Client) Get(ctx context.Context, key string) (*Item, error)

func (*Client) GetMulti

func (c *Client) GetMulti(ctx context.Context, keys ...string) (_ map[string]*Item, retErr error)

func (*Client) Inc

func (c *Client) Inc(ctx context.Context, key string, delta uint64, o ...Option) (uint64, error)

func (*Client) Set

func (c *Client) Set(ctx context.Context, i *Item, o ...Option) error

type Item

type Item struct {
	Key   string
	Value Value
	Flags uint16
	// contains filtered or unexported fields
}

type Option

type Option func(c *opts)

func WithExpiration

func WithExpiration(exp, scale uint32) Option

https://github.com/memcached/memcached/wiki/ProgrammingTricks#scaling-expiration при истечении срока жизни первый зарос получает cache miss, все остальные -- hit, в течении указанного scale

func WithInitial

func WithInitial(v uint64) Option

Inc only

func WithMinUses

func WithMinUses(number uint32) Option

func WithNamespace

func WithNamespace(ns string) Option

type Options

type Options struct {
	Addrs               []string
	PickServer          func(key string) []string
	KeyHashFunc         func(key string) []byte
	DialTimeout         time.Duration
	ConnMaxLifetime     time.Duration
	MaxIdleConnsPerAddr int
}

type Value

type Value []byte

func (*Value) Marshal

func (val *Value) Marshal(v any) (err error)

func (Value) Unmarshal

func (val Value) Unmarshal(v any) error

Directories

Path Synopsis
internal
proto

Jump to

Keyboard shortcuts

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