cache

package
v3.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2023 License: MIT Imports: 15 Imported by: 2

README

Cache module

The Cache module provides an easy interface to cache things in flamingo.

The basic concept is, that there is a so called "cache frontend" - that offers an interface to cache certain types, and a "cache backend" that takes care about storing(persiting) the cache entry.

Caching HTTP responses from APIs

A typical use case is, to cache responses from (slow) backends that you need to call.

First define an injection to get a HTTPFrontend cache injected:

MyApiClient struct {
      Cache            *cache.HTTPFrontend                  `inject:"myservice"`
}

We use annotation to be able to individually configure the requested Cache. So our binding may look like:

injector.Bind((*cache.HTTPFrontend)(nil)).AnnotatedWith("myservice").In(dingo.Singleton)

Then when you request your API you can wrap the result in the cache and provide a cache loader function. The HTTPFrontend Cache then makes sure that:

  • If there is a cache hit - return it within the given "GraceTime" - and eventually do a new request if cache "LiveTime" is over.
  • Requests for the same key are done in "single flight" if cache is empty meaning that even if there may be 1000 parallel requests only the first one will be executed against the backend service and the other wait for the result

Example:

loadData :=  func(ctx context.Context) (*http.Response, *cache.Meta, error) {
    r, err := http.DefaultClient.Do(req.WithContext(ctx))
    if err != nil {
        return nil, nil, err
    }
    //cache semantic errors for certain time to avoid recalling the same request
    if r.StatusCode == http.StatusNotFound {
        return r, &cache.Meta{
            Lifetime:  5 * time.Minute,
            Gracetime: 300 * time.Second,
        }, nil
    }
    //cache semantic errors for certain time to avoid recalling the same request
    if r.StatusCode != http.StatusOK {
        return r, &cache.Meta{
            Lifetime:  10 * time.Second,
            Gracetime: 30 * time.Second,
        }, nil
    }
    return r, nil, nil
}
response, err := apiclient.Cache.Get(requestContext, u.String(), loadData)

Cache backends

Currently there are the following backends available:

  • inMemoryCache (caches in memory - and therefore is a very fast cache)
  • fileBackend (caches in filesystem )
  • nullBackend (caches nothing)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Backend

type Backend interface {
	Get(key string) (entry *Entry, found bool) // Get a cache entry
	Set(key string, entry *Entry) error        // Set a cache entry
	//Peek(key string) (entry *CacheEntry, found bool) // Peek for a cache entry, this should not trigger key-updates or weight/priorities to be changed
	Purge(key string) error
	PurgeTags(tags []string) error
	Flush() error
}

Backend describes a cache backend, responsible for storing, flushing, setting and getting entries

func NewInMemoryCache

func NewInMemoryCache() Backend

NewInMemoryCache creates a new lru TwoQueue backed cache backend

type Entry

type Entry struct {
	Meta Meta
	Data interface{}
}

Entry is a cached object with associated meta data

type FileBackend

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

FileBackend is a cache backend which saves the data in files

func NewFileBackend

func NewFileBackend(baseDir string) *FileBackend

NewFileBackend returns a FileBackend operating in the given baseDir

func (*FileBackend) Flush

func (*FileBackend) Flush() error

Flush is not supported by FileBackend and does nothing

func (*FileBackend) Get

func (fb *FileBackend) Get(key string) (entry *Entry, found bool)

Get reads a cache entry

func (*FileBackend) Purge

func (fb *FileBackend) Purge(key string) error

Purge deletes a cache entry

func (*FileBackend) PurgeTags

func (*FileBackend) PurgeTags(tags []string) error

PurgeTags is not supported by FileBackend and does nothing

func (*FileBackend) Set

func (fb *FileBackend) Set(key string, entry *Entry) error

Set writes a cache entry

type HTTPFrontend

type HTTPFrontend struct {
	singleflight.Group
	// contains filtered or unexported fields
}

HTTPFrontend stores and caches http responses

func GetHTTPFrontendCacheWithNullBackend

func GetHTTPFrontendCacheWithNullBackend() *HTTPFrontend

GetHTTPFrontendCacheWithNullBackend helper for tests

func (*HTTPFrontend) Get

func (hf *HTTPFrontend) Get(ctx context.Context, key string, loader HTTPLoader) (*http.Response, error)

Get a http response, with tags and a loader the tags will be used when the entry is stored

func (*HTTPFrontend) Inject

func (hf *HTTPFrontend) Inject(backend Backend, logger flamingo.Logger) *HTTPFrontend

Inject HTTPFrontend dependencies

type HTTPLoader

type HTTPLoader func(context.Context) (*http.Response, *Meta, error)

HTTPLoader returns a response. it will be cached unless there is an error. this means 400/500 responses are cached too!

type Meta

type Meta struct {
	Tags                []string
	Lifetime, Gracetime time.Duration
	// contains filtered or unexported fields
}

Meta describes life and gracetimes, as well as tags, for cache entries

type NullBackend

type NullBackend struct{}

NullBackend does not store anything

func (*NullBackend) Flush

func (*NullBackend) Flush() error

Flush nothing

func (*NullBackend) Get

func (*NullBackend) Get(key string) (entry *Entry, found bool)

Get nothing

func (*NullBackend) Purge

func (*NullBackend) Purge(key string) error

Purge nothing

func (*NullBackend) PurgeTags

func (*NullBackend) PurgeTags(tags []string) error

PurgeTags purges nothing

func (*NullBackend) Set

func (*NullBackend) Set(key string, entry *Entry) error

Set nothing

type StringFrontend

type StringFrontend struct {
	singleflight.Group
	// contains filtered or unexported fields
}

StringFrontend manages cache entries as strings

func (*StringFrontend) Get

func (sf *StringFrontend) Get(key string, loader StringLoader) (string, error)

Get and load string cache entries

func (*StringFrontend) Inject

func (sf *StringFrontend) Inject(backend Backend)

Inject StringFrontend dependencies

type StringLoader

type StringLoader func() (string, *Meta, error)

StringLoader is used to load strings for singleflight cache loads

Jump to

Keyboard shortcuts

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