gcache

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2024 License: MIT Imports: 20 Imported by: 0

README

gcache Go Reference Go codecov

gcache is a gRPC caching library that provides a simple way to cache gRPC requests and responses. It is designed to be used with gRPC services that have a high request rate and where caching can improve the performance of the service.

It uses a plain old ETag and If-None-Match headers to cache the responses. The cache is stored in memory and is not persistent (unless you use a persistent cache store).

It also provides a server-side caching implementation.

Installation

go get -u github.com/cappuccinotm/gcache

Usage

Client-side caching
icptr := gcache.NewInterceptor(gcache.WithLogger(slog.Default()))
conn, err := grpc.NewClient("localhost:8080",
    grpc.WithTransportCredentials(insecure.NewCredentials()),
    grpc.WithUnaryInterceptor(icptr.UnaryClientInterceptor()),
)
if err != nil {
    return fmt.Errorf("dial localhost:8080: %w", err)
}

client := order.NewOrderServiceClient(conn)

Client-side interceptor seeks for server's ETag header in the response, if the server has provided one, it stores the response in the cache. When the client sends a request, the interceptor adds the If-None-Match header to the request. If the server responds with code Aborted and the ETag header, equal to the one that has been sent by client, the interceptor returns the cached response.

Server-side caching
icptr := gcache.NewInterceptor(gcache.WithLogger(slog.Default()))
server := grpc.NewServer(
    grpc.WithTransportCredentials(insecure.NewCredentials()),
    grpc.WithUnaryInterceptor(icptr.UnaryServerInterceptor()),
)

Server-side interceptor always sends the cached response unless client has specifically set the Cache-Control: no-cache header.

Documentation

Overview

Package gcache provides caching interceptors for gRPC clients.

Index

Constants

This section is empty.

Variables

View Source
var ErrKey = "error"

ErrKey specifies the error key for logging.

Functions

func ETag

func ETag(ctx context.Context) string

ETag returns the ETag from the context.

func NotChanged

func NotChanged(ctx context.Context, etag string) error

NotChanged responds to the client with codes.Aborted and the etag, meaning that the client should use the cached value.

Types

type Entry

type Entry struct {
	Value []byte `json:"value"`
	ETag  string `json:"etag"`
}

Entry is a cache entry to store.

type Interceptor

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

Interceptor is a cache interceptor. It looks over the ETag header and caches the response ONLY if the ETag is present.

func NewInterceptor

func NewInterceptor(opts ...Option) *Interceptor

NewInterceptor makes a new Interceptor.

func (*Interceptor) UnaryClientInterceptor

func (c *Interceptor) UnaryClientInterceptor() grpc.UnaryClientInterceptor

UnaryClientInterceptor returns a new unary client interceptor that caches the response.

func (*Interceptor) UnaryServerInterceptor

func (c *Interceptor) UnaryServerInterceptor() grpc.UnaryServerInterceptor

UnaryServerInterceptor returns a new unary server interceptor that caches the response. It doesn't use ETag header, but Cache-Control header.

type LRUBackend

type LRUBackend interface {
	Add(key string, value Entry) (evicted bool)
	Get(key string) (value Entry, ok bool)
	Remove(key string) (present bool)
}

LRUBackend specifies interface to be implemented by hashicorp LRU cache backends.

type Option

type Option func(*Interceptor)

Option is a configuration option.

func WithCodec

func WithCodec(codec encoding.Codec) Option

WithCodec sets the codec.

func WithFilter

func WithFilter(rx *regexp.Regexp) Option

WithFilter sets the filter that is used to match the methods that must be cached.

func WithLogger

func WithLogger(l *slog.Logger) Option

WithLogger sets the logger.

func WithStore

func WithStore(store Store) Option

WithStore sets the store.

type RawBytesCodec

type RawBytesCodec struct{}

RawBytesCodec sets the received bytes as-is to the target, whether it is a byte slice or a proto.Message. For proto.Message, it uses proto.Marshal and proto.Unmarshal.

func (RawBytesCodec) Marshal

func (RawBytesCodec) Marshal(v any) ([]byte, error)

Marshal returns the received byte slice as is.

func (RawBytesCodec) Name

func (RawBytesCodec) Name() string

Name returns the name of the codec.

func (RawBytesCodec) Unmarshal

func (RawBytesCodec) Unmarshal(data []byte, v any) error

Unmarshal sets the received bytes as is to the target.

type RedisOption

type RedisOption func(*redisStore)

RedisOption is a configuration option.

func WithRedisLogger

func WithRedisLogger(l *slog.Logger) RedisOption

WithRedisLogger sets the logger.

func WithRedisSkipLocalCache

func WithRedisSkipLocalCache(skipLocalCache bool) RedisOption

WithRedisSkipLocalCache sets the skipLocalCache.

func WithRedisTTL

func WithRedisTTL(ttl time.Duration) RedisOption

WithRedisTTL sets the TTL.

type Store

type Store interface {
	Get(ctx context.Context, key string) (e Entry, ok bool)
	Set(ctx context.Context, key string, e Entry)
	Remove(ctx context.Context, key string)
}

Store is a cache store.

func NewLRU

func NewLRU(backend LRUBackend) Store

NewLRU wraps hashicorp/golang-lru/v2 cache implementations to be used as interceptor's store.

func NewRedis

func NewRedis(backend *rediscache.Cache, opts ...RedisOption) Store

NewRedis returns a new redisStore cache store.

Directories

Path Synopsis
internal
tspb
Package tspb contains a mock of gRPC service for testing purposes.
Package tspb contains a mock of gRPC service for testing purposes.

Jump to

Keyboard shortcuts

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