memc

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2026 License: BSD-3-Clause Imports: 15 Imported by: 0

README

memc

memc is a modern and generics enabled memcached client library for Go.

requires go1.23+

October 2024: (!) This package is very new and may contain bugs and missing features.

Getting Started

The memc package can be added to a Go project with go get.

go get cattlecloud.net/go/memc@latest
import "cattlecloud.net/go/memc"
Examples
Connecting to memcached.

Supports connecting via TCP or Unix Domain Socket.

client := memc.New(
  []string{"localhost:11211"},
)

For sockets, simply specify the socket filepath.

client := memc.New(
  []string{"/var/lib/app/cache.socket"},
)
Setting a value in memcached.
err := memc.Set(client, "my/key/name", "some_value")

Note that the memc library can handle arbitrary value types, as long as they can be encoded using Go's built-in gob package. The library automatically handles serialization on writes and de-serialization on reads.

err := memc.Set(client, "my/key/name", &Person{Name: "Bob"})
Reading a value from memcached.

The memc package will automatically convert the value []byte into the type of your Go variable.

value, err := memc.Get[T](client, "my/key/name")
Incrementing/Decrementing a counter in memcached.

The memc package provides Increment and Decrement for increasing or decreasing a value by a given delta. Note that the value must already be stored, and must be in the form of an ASCII string representation of a number. The delta value must be positive.

err := memc.Set(client, "/my/counter", "100")

Using Increment to increase the counter value by 1.

v, err := memc.Increment("/my/counter", 1)
// v is now 101

Using Decrement to decrease the value by 5.

v, err := memc.Decrement("/my/counter", 5)
// v is now 96
Sharding memcached instances.

The memcached can handle sharding writes and reads across multiple memcached instances. It does this by hashing the key space and deterministically choosing an assigned instance. To enable this behavior simply give the Client each memcached instance address.

client := memc.New(
  []string{
    "10.0.0.1:11211",
    "10.0.0.2:11211",
    "10.0.0.3:11211",
  },
)
Configuring default expiration.

The Client sets a default expiration time on each value. This expiration time can be configured when creating the client.

client := memc.New(
  // ...
  SetDefaultTTL(2 * time.Minute),
)
Configuration idle connection pool.

The Client maintains an idle connection pool for each memcached instance it has connected to. The number of idle connections to maintain per instance can be adjusted.

client := memc.New(
  // ...
  SetIdleConnections(4),
)
Closing the client.

The Client can be closed so that idle connections are closed and no longer consuming resources. In-flight requests will be closed once complete. Once closed the client cannot be reused.

_ = memc.Close()
License

The cattlecloud.net/go/memc module is open source under the BSD-3-Clause license.

Documentation

Overview

Package memc provides a modern memcached client for Go.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCacheMiss    = errors.New("memc: cache miss")
	ErrKeyNotValid  = errors.New("memc: key is not valid")
	ErrNotStored    = errors.New("memc: item not stored")
	ErrNotFound     = errors.New("memc: item not found")
	ErrConflict     = errors.New("memc: CAS conflict")
	ErrExpiration   = errors.New("memc: expiration ttl is not valid")
	ErrClientClosed = errors.New("memc: client has been closed")
	ErrNegativeInc  = errors.New("memc: increment delta must be non-negative")
	ErrNonNumeric   = errors.New("memc: cannot increment non-numeric value")
	ErrCommandIssue = errors.New("memc: got command error response")
)

Functions

func Add

func Add[T any](c *Client, key string, item T, opts ...Option) error

Add will store the item using the given key, but only if no item currently exists. New items are at the top of the LRU.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

func AddMulti added in v0.3.0

func AddMulti[T any](c *Client, items []*Pair[string, T], opts ...Option) error

AddMulti will store each item in items using the item's associated key, but only if the item does not currently exist. New items are at the top of the LRU.

Errors are accumulated using errors.Join.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

func Append added in v0.5.0

func Append[T any](c *Client, key string, item T, opts ...Option) error

Append will append the given value to the value associated with the given key.

Append differs from Set in that it is meant to add additional data to an existing key, rather than replace the existing value entirely. The key must already exist.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

func CompareAndSwap added in v0.5.0

func CompareAndSwap[T any](c *Client, key string, cas CAS, item T, opts ...Option) error

CompareAndSwap will store the item using the given key, but only if the CAS token matches the current value's CAS token. This provides atomic compare-and-swap functionality for optimistic locking.

If the key does not exist, ErrNotFound is returned.

If the CAS token does not match (meaning the value was modified since it was retrieved with Gets), ErrConflict is returned.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

func Decrement

func Decrement[T Countable](c *Client, key string, delta T) (T, error)

Decrement will decrement the value associated with the given key by delta.

Note: the value must be an ASCII integer. It must have been initially stored as a string value, e.g. by using Set. The delta value must be positive.

Set(client, "counter", "100")
Decrement(client, "counter", 1) // counter = 99

func Delete

func Delete(c *Client, key string) error

Delete will remove the value associated with key from memcached.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

func Flush added in v0.5.0

func Flush(c *Client, timeout time.Duration) error

Flush will delete all items from memcached.

The timeout parameter is optional. A timeout of 0 means flush right now. A non-zero timeout will delay the flush by that many seconds.

Note: this operation is performed on a single memcached server, even when the Client is configured with multiple server addresses. This is intentional, as flush is typically used by local administration tools that connect to a single memcached instance.

func Get

func Get[T any](c *Client, key string) (T, error)

Get the value associated with the given key.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

func Increment

func Increment[T Countable](c *Client, key string, delta T) (T, error)

Increment will increment the value associated with the given key by delta.

Note: the value must be an ASCII integer. It must have been initially stored as a string value, e.g. by using Set. The delta value must be positive.

Set(client, "counter", "100")
Increment(client, "counter", 1) // counter = 101

func Prepend added in v0.5.0

func Prepend[T any](c *Client, key string, item T, opts ...Option) error

Prepend will prepend the given value to the value associated with the given key.

Prepend differs from Set in that it is meant to add additional data to an existing key, rather than replace the existing value entirely. The key must already exist.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

func Replace added in v0.5.0

func Replace[T any](c *Client, key string, item T, opts ...Option) error

Replace will store the item using the given key, but only if the key already exists. New items are at the top of the LRU.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

func Set

func Set[T any](c *Client, key string, item T, opts ...Option) error

Set will store the item using the given key, possibly overwriting any existing data. New items are at the top of the LRU.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

func SetMulti added in v0.3.0

func SetMulti[T any](c *Client, items []*Pair[string, T], opts ...Option) error

SetMulti will store each item in items using the item's associated key, possibly overwritting any existing data. New items are at the top of the LRU.

Errors are accumulated using errors.Join.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

One or more Option(s) may be applied to configure things such as the value expiration TTL or its associated flags.

Types

type CAS added in v0.5.0

type CAS uint64

CAS represents a Compare-And-Swap token used for optimistic locking. It is returned by Gets and must be provided to CompareAndSwap to atomically update a value.

func Gets added in v0.5.0

func Gets[T any](c *Client, key string) (T, CAS, error)

Gets the value associated with the given key, along with its CAS token.

The CAS token can be used with CompareAndSwap to atomically update the value, providing optimistic locking. If the value has been modified since it was retrieved, CompareAndSwap will return an ErrConflict error.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

type Client

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

A Client is used for making network requests to memcached instances.

Use the package functions Set, Get, Delete, etc. by providing this Client to manage data in memcached.

func New

func New(instances []string, opts ...ClientOption) *Client

New creates a new Client capable of sharding across the given set of instances and pooling connections to each instance.

Certain behaviors can be configured by specifying one or more ClientOption options.

func (*Client) Close

func (c *Client) Close() error

Close will close all idle connections and prevent existing connections from becoming idle. Future use of the Client will fail.

type ClientOption

type ClientOption func(c *Client)

func SetClock added in v0.5.0

func SetClock(f ClockFunc) ClientOption

SetClock sets the ClockFunc used for getting the current time.

If unset the default is to use the time.Now function.

Note this should typically only be set in testing.

func SetDefaultTTL

func SetDefaultTTL(expiration time.Duration) ClientOption

SetDefaultTTL adjusts the default expiration time of values set into the memcached instance(s).

If unset the default expiration TTL is 1 hour.

The expiration time must be more than 1 second, or set to 0 to indicate no expiration time (and values stay in the cache indefinitely).

func SetDialTimeout

func SetDialTimeout(timeout time.Duration) ClientOption

SetDialTimeout adjusts the amount of time to wait on establishing a TCP connection to the memached instance(s).

If unset the default timeout is 5 seconds.

func SetIdleConnections

func SetIdleConnections(count int) ClientOption

SetIdleConnections adjusts the maximum number of idle connections to maintain for each memcached instance.

If unset the default idle connection limit is 1.

Note that idle connections are created on demand, not at startup.

type ClockFunc added in v0.5.0

type ClockFunc func() time.Time

ClockFunc is a function that returns the current time.

Normally this should just be the time.Now function.

type Countable

type Countable interface {
	~uint8 | ~uint16 | ~uint32 | ~uint64 | ~int
}

Countable represents types that work with Increment and Decrement operations.

Note: memcached does not allow negative values for either operation.

type ItemStatistics added in v0.5.0

type ItemStatistics struct {
	Class               int `json:"slab_class"`
	Number              int `json:"number"`
	NumberHot           int `json:"number_hot"`
	NumberWarm          int `json:"number_warm"`
	NumberCold          int `json:"number_cold"`
	AgeHot              int `json:"age_hot"`
	AgeWarm             int `json:"age_warm"`
	Age                 int `json:"age"`
	MemRequested        int `json:"mem_requested"`
	Evicted             int `json:"evicted"`
	EvictedNonZero      int `json:"evicted_nonzero"`
	EvictedTime         int `json:"evicted_time"`
	OutOfMemory         int `json:"outofmemory"`
	TailRepairs         int `json:"tailrepairs"`
	Reclaimed           int `json:"reclaimed"`
	ExpiredUnfetched    int `json:"expired_unfetched"`
	EvictedUnfetched    int `json:"evicted_unfetched"`
	EvictedActive       int `json:"evicted_active"`
	CrawlerReclaimed    int `json:"crawler_reclaimed"`
	CrawlerItemsChecked int `json:"crawler_items_checked"`
	LRUTailReflocked    int `json:"lrutail_reflocked"`
	MovesToCold         int `json:"moves_to_cold"`
	MovesToWarm         int `json:"moves_to_warm"`
	MovesWithinLRU      int `json:"moves_within_lru"`
	DirectReclaims      int `json:"direct_reclaims"`
	HitsToHot           int `json:"hits_to_hot"`
	HitsToWarm          int `json:"hits_to_warm"`
	HitsToCold          int `json:"hits_to_cold"`
	HitsToTemp          int `json:"hits_to_temp"`
}

func StatsItems added in v0.5.0

func StatsItems(c *Client) ([]*ItemStatistics, error)

StatsItems returns item statistics for a single memcached server.

Note: this operation is performed on a single memcached server, even when the Client is configured with multiple server addresses. This is intentional, as stats is typically used by local monitoring tools that connect to a single memcached instance.

type Option

type Option func(o *Options)

Option to apply when executing a verb like Get, Set, etc.

func Flags

func Flags(flags int) Option

Flags applies the given flags on the value being set.

func TTL

func TTL(expiration time.Duration) Option

TTL applies the given expiration time to set on the value being set.

The expiration must be greater than 1 second, or 0, indicating the value will not expire automatically.

type Options

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

Options contains configuration parameters that may be applied when executing a verb like Get, Set, etc.

type Pair added in v0.3.0

type Pair[T, U any] struct {
	A T
	B U
}

A Pair associates two elements.

func GetMulti added in v0.3.0

func GetMulti[T any](c *Client, keys []string) []*Pair[T, error]

Get the values associated with the given keys. One Pair[T, error] return value for each of the given keys, in the same order.

Uses Client c to connect to a memcached instance, and automatically handles connection pooling and reuse.

type Slab added in v0.5.0

type Slab struct {
	Class         int `json:"slab_class"`
	ChunkSize     int `json:"chunk_size"`
	ChunksPerPage int `json:"chunks_per_page"`
	TotalPages    int `json:"total_pages"`
	TotalChunks   int `json:"total_chunks"`
	UsedChunks    int `json:"used_chunks"`
	FreeChunks    int `json:"free_chunks"`
	FreeChunksEnd int `json:"free_chunks_end"`
	GetHits       int `json:"get_hits"`
	CmdSet        int `json:"cmd_set"`
	DeleteHits    int `json:"delete_hits"`
	IncrementHits int `json:"incr_hits"`
	DecrementHits int `json:"decr_hits"`
	CASHits       int `json:"cas_hits"`
	CASBadVal     int `json:"cas_badval"`
	TouchHits     int `json:"touch_hits"`
}

type SlabStatistics added in v0.5.0

type SlabStatistics struct {
	ActiveSlabs   int     `json:"active_slabs"`
	TotalMalloced int     `json:"total_malloced"`
	Slabs         []*Slab `json:"slabs"`
}

func StatsSlabs added in v0.5.0

func StatsSlabs(c *Client) (*SlabStatistics, error)

StatsSlabs returns slab statistics for a single memcached server.

Note: this operation is performed on a single memcached server, even when the Client is configured with multiple server addresses. This is intentional, as stats is typically used by local monitoring tools that connect to a single memcached instance.

type Statistics added in v0.5.0

type Statistics struct {
	Runtime struct {
		PID         int    `json:"pid"`
		Uptime      int    `json:"uptime"`
		Time        int    `json:"time"`
		Version     string `json:"version"`
		LibEvent    string `json:"libevent"`
		PointerSize int    `json:"pointer_size"`
		Threads     int    `json:"threads"`
	}

	Resources struct {
		RUsageUser   float64 `json:"rusage_user"`
		RUsageSystem float64 `json:"rusage_system"`
	}

	Connections struct {
		Max        int `json:"max_connections"`
		Current    int `json:"curr_connections"`
		Total      int `json:"total_connections"`
		Rejected   int `json:"rejected_connections"`
		Structures int `json:"connection_structures"`
	}

	Commands struct {
		Get   int `json:"cmd_get"`
		Set   int `json:"cmd_set"`
		Flush int `json:"cmd_flush"`
		Touch int `json:"cmd_touch"`
		Meta  int `json:"cmd_meta"`

		Hit struct {
			Get       int `json:"get_hits"`
			Delete    int `json:"delete_hits"`
			Increment int `json:"incr_hits"`
			Decrement int `json:"decr_hits"`
			Touch     int `json:"touch_hits"`
			CAS       int `json:"cas_hits"`
		}

		Miss struct {
			Get       int `json:"get_misses"`
			Delete    int `json:"delete_misses"`
			Increment int `json:"incr_misses"`
			Decrement int `json:"decr_misses"`
			Touch     int `json:"touch_misses"`
			CAS       int `json:"cas_misses"`
		}

		Failure struct {
			GetExpired  int `json:"get_expired"`
			GetFlushed  int `json:"get_flushed"`
			CASBadValue int `json:"cas_badval"`
		}
	}

	Items struct {
		Bytes   int `json:"bytes"`
		Current int `json:"curr_items"`
		Total   int `json:"total_items"`
	}
}

func Stats added in v0.5.0

func Stats(c *Client) (*Statistics, error)

Stats returns runtime statistics for a single memcached server.

Note: this operation is performed on a single memcached server, even when the Client is configured with multiple server addresses. This is intentional, as stats is typically used by local monitoring tools that connect to a single memcached instance.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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