recache

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: May 23, 2019 License: MIT Imports: 9 Imported by: 0

README

GoDoc Build Status codecov

recache

recursive compressed cache library and server

recache is a library (standalone server implementation pending) that enables you to easily construct caches with reusable components stored efficiently in compressed buffers and efficiently streamed to any client consumer.

This is based on the fact that any compliant GZIP decoder decompresses a concatenation of individually compressed component GZIP buffers to the equivalent of the concatenation of the source component buffers. This allows recache to generate a tree of components on request that can be sequentially written to a consumer such as a HTTP request or buffer builder with zero extra buffer copies or allocation.

Unlike more traditional caches, that provide a more or less CRUD-like interface, recache abstracts cache hits and misses from the client. The client instead provides a lookup key and lambda to generate a new cache record. In case of cache miss (of the targeted record or any included record references) recache calls the provided lambda, compresses the result, generates hashes and ETags for versioning and registers any recursively looked up records from the same or other cache instances.

On client request a component tree is generated for this specific request. This allows recache to pass any errors, that occurred during generation, before writing a single byte to the client, enabling simple error propagation. Once a component tree has been generated it is immutable and safe to be streamed to the client, even if a component is evicted concurrently during the streaming.

recache guarantees work deduplication with concurrent requests requesting a missing record. In such a case the first client will proceed to generate the cache record data and any subsequent clients will block until this generation has completed. Once generation is completed, the record is immutable and any subsequent clients will simply consume it after a cheap atomic flag check.

A single cache can contain multiple frontends. A frontend's stored data is subject to the same memory and LRU limits as its parent cache, however each frontend has it's own private key space and a possibly different new record generation lambda.

recache provides configurable per-cache instance maximum used memory and last record use time limits. In case of overflow the least recently used records are evicted from the cache until the overflow is eventually mitigated. recache also provides methods for evicting records by key, by matcher functions or clearing the cache or frontend by evicting all records.

recache does not perform any actions without calls to the library. This means that recache has zero passive runtime costs, if you exclude the cost of managing the memory used by recache on the Go runtime.

TODO: benchmarks

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache

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

Unified storage for cached records with specific eviction parameters

func NewCache

func NewCache(memoryLimit uint, lruLimit time.Duration) (c *Cache)

Create new cache with specified memory and LRU eviction limits. After either of these are exceeded, the least recently used cache records will be evicted, until the requirements are satisfied again. Note that this eviction is eventual and not immediate for optimisation purposes.

Pass in zero values to ignore either or both eviction limits.

func (*Cache) EvictAll

func (c *Cache) EvictAll()

Evict all records from cache

func (*Cache) NewFrontend

func (c *Cache) NewFrontend(get Getter) *Frontend

Create new Frontend for accessing the cache. A Frontend must only be created using this method.

get() will be used for generating fresh cache records for the given key by the cache engine. These records will be stored by the cache engine and must not be modified after get() returns. get() must be thread-safe.

type Frontend

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

A frontend for accessing the cache contents

func (*Frontend) Evict

func (f *Frontend) Evict(k Key)

Evict a record by key, if any

func (*Frontend) EvictAll

func (f *Frontend) EvictAll()

Evict all records from frontend

func (*Frontend) EvictByFunc

func (f *Frontend) EvictByFunc(fn func(Key) (bool, error)) error

Evict keys from frontend using matcher function fn. fn returns true, if a key must be evicted.

func (*Frontend) WriteHTTP

func (f *Frontend) WriteHTTP(k Key, w http.ResponseWriter, r *http.Request,
) (n int64, err error)

Retrieve or generate data by key and write it to w. Writes ETag to w and returns 304 on ETag match without writing data. Sets "Content-Encoding" header to "gzip".

func (*Frontend) WriteTo

func (f *Frontend) WriteTo(k Key, w io.Writer) (n int64, err error)

Retrieve or generate data by key and write it to w

type Getter

type Getter func(Key, *RecordWriter) error

Generates fresh cache records for the given key by writing to RecordWriter. Getter must be thread-safe.

type Key

type Key interface{}

Value used to store entries in the cache. Must be a type suitable for being a key in a Go map.

type RecordWriter

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

Provides utility methods for building record buffers and recursive record trees

func (*RecordWriter) Include

func (rw *RecordWriter) Include(f *Frontend, k Key) (err error)

Include data from passed frontend by key and link it to rw. The record generated by rw will automatically be evicted from its parent cache on eviction of the included record.

func (*RecordWriter) ReadFrom

func (rw *RecordWriter) ReadFrom(r io.Reader) (n int64, err error)

Read non-gzipped data from r and write it to the record for storage

func (*RecordWriter) Write

func (rw *RecordWriter) Write(p []byte) (n int, err error)

Write non-gzipped data to the record for storage

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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