cacher

package module
v0.0.0-...-e189903 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2016 License: MIT Imports: 7 Imported by: 0

README

Cacher

Cacher is a simple embedded caching mechanism for caching stuff in your Go applications. It supports some advanced reverse proxy modes of operation such as read/write through, touch and refresh. It is not prepared to be a networked server on its own, but you may wrap it around a mux/http server should you need it.

It uses boltdb for presistence: https://github.com/boltdb/bolt

Installation

Get the dependencies and the code:

go get github.com/boltdb/bolt
go get github.com/ccarvalheira/cacher

Usage

Simple usage:
import "github.com/ccarvalheira/cacher"
import "time"
(...)
cache := cacher.NewCacher("/tmp", "zoneOne", "zoneTwo")
defer cache.Close()

expiration := int64(100) //in seconds
item := cache.CacheItem{[]byte("data goes here"), time.Now().Unix()+expiration}
err := cache.Set("zoneOne", "key1", item)
if err != nil {
  log.Println("something went wrong:", err)
}
retrievedItem, err := cache.Get("zoneOne", "key1")

Usage with reverse proxy stuff:
import "github.com/ccarvalheira/cacher"

func myOrigin() ([]byte, error) {
  //origin functions may be as complicated or as simple as you want
  //including making requests over the network, database calls, etc
  //if origin returns an error, cacher will stop the current operation and bubble the error up
  return []byte("some data here"), nil
}

cache := cacher.NewCacher("/tmp", "zoneOne", "zoneTwo")
defer cache.Close()


item, err := cache.WriteThrough(myOrigin, "zoneOne", "key1", 123)
storedItem, err := cache.Get("zoneOne", "key1")

log.Println(item.Equal(storedItem))

For more usage examples and information, please consult the cacher_test.go file.

Other considerations

Currently, there is no mechanism for controlling the size of the cache. This should either be done manually or added later on. This implementation is designed to be embedded in an application and not a networked service.

Benchmarks on the code show that making concurrent requests to the cache results in much higher performance.

Compared to nginx cache, this implementation is 10~20% slower. This difference is likely due to the maturity of the performance optimizations in nginx compared to cacher and also because of the extra network hops inserted in the tests. These tests were conducted at my current company (at time of writing) with a particular architecture in mind so we had an idea of what the actual difference would be.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCacheExpired = errors.New("item is expired")
	ErrCacheMiss    = errors.New("item is not present")
	ErrCacheHit     = errors.New("item is present")
	ErrCacheBypass  = errors.New("item was not searched in cache")
)

Functions

This section is empty.

Types

type CacheItem

type CacheItem struct {
	//The bytes to actually store.
	Body []byte
	//The Unix timestamp in seconds for which this item is valid.
	//When setting the cache item you will probably want to do something like: time.Now().Unix()+123, where 123 is the validity of the item.
	Expiration int64
}

CacheItem is the definition if a cached item.

func (*CacheItem) Equal

func (c *CacheItem) Equal(other CacheItem) bool

Equal is a utility method for comparing the equality between two cache items.

type CacheMode

type CacheMode uint8

CacheMode determines which mode of operation should be applied when using the cache.

const (
	// ReadThroughMode will read from cache and in the case of a cache miss or expired, WILL NOT WRITE to the cache.
	ReadThroughMode CacheMode = iota
	// WriteThroughMode will read from cache and in the case of a cache miss or expired, WILL SET the cache key to origin.
	WriteThroughMode
	// RefreshMode will try to get the cached item. If it exists or is expired, it will overwrite it with origin. Otherwise, nothing happens.
	// This is used to refresh cache items if they already exist in cache.
	RefreshMode
	// BypassMode will simply invoke origin and no other Cacher methods.
	BypassMode
	// ReloadMode will bypass reading from cache but WILL SET the cache key to origin.
	// This is used to touch items into cache.
	ReloadMode
)

type Cacher

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

Cacher manages a persistent cache with many zones. Managing the zones' size is not supported.

func NewCacher

func NewCacher(basePath string, zoneNames ...string) *Cacher

NewCacher creates a new Cacher. It takes in the base path to write the zones to. A variable number of zoneNames may be specified. The names will be the actual filenames on the filesystem. Passing no zoneNames will cause NewCacher to panic.

func (*Cacher) Bypass

func (c *Cacher) Bypass(orig Origin, zoneName, key string, expires int64) (CacheItem, error)

Bypass completely ignores the cache and invokes origin directly.

func (*Cacher) Close

func (c *Cacher) Close()

Close closes all zones' handlers and does not remove any data. This should be invoked prior to shutdown.

func (*Cacher) Delete

func (c *Cacher) Delete(zoneName, key string)

Deletes an item from the cache.

func (*Cacher) Get

func (c *Cacher) Get(zoneName, key string) (item CacheItem, err error)

Get retrieves a CacheItem indexed by zoneName and key, returning the item and the error ErrCacheHit. If the item does not exist, the error returned is ErrCacheMiss. If the item is expired, the error returned is ErrCacheExpired. If some other error occured, it will be returned.

func (*Cacher) PickMode

func (c *Cacher) PickMode(mode CacheMode) func(Origin, string, string, int64) (CacheItem, error)

PickMode returns one of the following functions: ReadThrough, WriteThrough, Refresh, Bypass or Reload depending on the CacheMode passed in. This is just a convenience. We pass it the mode and get the appropriate function that we can immediately invoke. Since all advanced functions have the same signature, changing the mode of operation is as simple as changing the argument to this function.

func (*Cacher) Purge

func (c *Cacher) Purge(zoneName string)

Purge completely removes a zone file from the filesystem and Cacher will stop referencing it.

func (*Cacher) PurgeAll

func (c *Cacher) PurgeAll()

PurgeAll invokes Purge for all of the Cacher's zones.

func (*Cacher) ReadThrough

func (c *Cacher) ReadThrough(orig Origin, zoneName, key string, expires int64) (CacheItem, error)

ReadThrough reads from cache but does not store result in cache.

func (*Cacher) Refresh

func (c *Cacher) Refresh(orig Origin, zoneName, key string, expires int64) (CacheItem, error)

Refresh refreshes the item if it exists. Returns nil if refreshed or ErrCacheMiss if nothing exists to refresh.

func (*Cacher) Reload

func (c *Cacher) Reload(orig Origin, zoneName, key string, expires int64) (CacheItem, error)

Reload does not read from cache but sets the result in cache.

func (*Cacher) Set

func (c *Cacher) Set(zoneName, key string, item CacheItem) error

Set sets a CacheItem to the given zone with the given key.

func (*Cacher) WriteThrough

func (c *Cacher) WriteThrough(orig Origin, zoneName, key string, expires int64) (CacheItem, error)

WriteThrough reads from cache and stores the result from origin in cache.

type Origin

type Origin func() ([]byte, error)

Origin is a type of function that is used by the advanced cache operations. Its usage allows Cacher to be used as a reverse proxy.

Jump to

Keyboard shortcuts

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