omnicache

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2025 License: MIT Imports: 9 Imported by: 0

README

Omnicache

Generic, high-performance, driver-based cache manager for Go

Go Reference Go Report Card Tests


Overview

Omnicache is a unified caching abstraction layer for Go — providing a simple, type-safe, and concurrent interface for multiple cache backends like:

  • Memory (in-memory store)
  • Redis / Valkey / Dragonfly
  • Your own driver

Omnicache supports:

  • Thread-safe and context-aware operations
  • Multiple registered stores (alias-based switching)
  • Generic (type-safe) accessors
  • Pluggable driver architecture
  • Clean, minimal API surface for readability and speed

Installation

go get github.com/shoraid/omnicache

Go version requirement:

Go 1.18+

Quick Start

1. Basic Example
package main

import (
    "context"
    "fmt"
    "time"

    "github.com/shoraid/omnicache"
    "github.com/shoraid/omnicache/drivers/memory"
)

func main() {
    ctx := context.Background()
    manager := omnicache.NewManager()

    memStore := memory.NewMemoryStore()
    _ = manager.Register("memory", memStore)

    _ = manager.Set(ctx, "username", "shoraid", 10*time.Minute)

    val, err := manager.Get(ctx, "username")
    if err != nil {
        panic(err)
    }

    fmt.Println("username:", val)
}

2. Using GetOrSet (Lazy Load)
profile, err := manager.GetOrSet(ctx, "user:123:profile", time.Hour, func() (any, error) {
    fmt.Println("fetching from DB...")
    return map[string]any{
        "id":   123,
        "name": "Alice",
    }, nil
})

3. Generic (Type-Safe) Access
user, err := omnicache.
    G[map[string]any](manager).
    GetOrSet(ctx, "user:123:profile", time.Minute, func() (map[string]any, error) {
        return map[string]any{"id": 123, "name": "Alice"}, nil
    })

fmt.Println(user["name"]) // "Alice"

4. Multiple Stores with Aliases

You can register multiple stores, set one as default, and access them via aliases dynamically. If no default is explicitly set, the first registered store automatically becomes the default.

// You can freely name your stores using any alias.
fastCache := redis.NewRedisWithClient(redisClient)
backupCache := memory.NewMemoryStore()

// Register both stores with custom aliases
_ = manager.Register("fast", fastCache)    // Redis store
_ = manager.Register("backup", backupCache) // Memory store

// Set the default store (if not set, the first registered store becomes default)
_ = manager.SetDefault("fast")

// Use default store (alias: "fast")
manager.Set(ctx, "foo", "baz", 0)

// Explicitly choose a store by alias
manager.Store("fast").Set(ctx, "foo", "baz", 0)   // Redis
manager.Store("backup").Set(ctx, "foo", "bar", 0) // Memory

Function Reference

Below is a quick summary of available Manager and GenericManager methods for reference:

Function Description
Register(alias, store) Register a new cache store with an alias. The first registered store becomes default if none is set.
SetDefault(alias) Set the store with the given alias as the default.
Store(alias) Switch between registered stores.
Get(ctx, key) Retrieve a cached value. Returns ErrCacheMiss if missing.
Has(ctx, key) Check if key exists and is not expired.
Set(ctx, key, value, ttl) Store a value with optional TTL.
GetOrSet(ctx, key, ttl, fn) Lazy load and cache computed value.
Delete(ctx, key) Remove one key safely.
DeleteByPattern(ctx, pattern) Remove keys matching pattern (glob/regex).
DeleteMany(ctx, keys...) Remove multiple keys.
DeleteManyByPattern(ctx, patterns...) Remove keys matching multiple patterns concurrently.
Clear(ctx) Remove all keys from current store.
G[T](manager) Type-safe generic wrapper for any type. Support Get and GetOrSet

Design Philosophy

“Write once, switch anywhere.”

Omnicache treats caching as an interchangeable layer.
Each driver implements the same Store contract for full portability.


License

MIT License © 2025 Shora

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCacheMiss              = errors.New("cache: cache miss")
	ErrInternal               = errors.New("cache: internal error")
	ErrInvalidConfig          = errors.New("cache: invalid config")
	ErrInvalidDefaultStore    = errors.New("cache: invalid default cache store")
	ErrInvalidStore           = errors.New("cache: invalid cache store")
	ErrStoreAlreadyRegistered = errors.New("cache: store already registered")
	ErrInvalidValue           = errors.New("cache: invalid value")
	ErrTypeMismatch           = errors.New("cache: value type mismatch")
)

Functions

This section is empty.

Types

type GenericManager

type GenericManager[T any] struct {
	// contains filtered or unexported fields
}

GenericManager provides a generic way to interact with the cache for any type T. It wraps the Manager and provides type-safe Get and GetOrSet methods.

func G

func G[T any](m *Manager) *GenericManager[T]

G returns a new GenericManager for the specified type T, bound to the given Manager instance. This allows for type-safe Get and GetOrSet operations.

func (*GenericManager[T]) Get

func (g *GenericManager[T]) Get(ctx context.Context, key string) (T, error)

Get retrieves a value of type T from the cache. Returns ErrTypeMismatch if the cached value cannot be converted to T.

func (*GenericManager[T]) GetOrSet

func (g *GenericManager[T]) GetOrSet(ctx context.Context, key string, ttl time.Duration, defaultFn func() (T, error)) (T, error)

GetOrSet retrieves a value of type T from the cache if present; otherwise, it computes the value lazily by calling defaultFn, stores it with the given TTL, and returns it. If storing fails, it still returns the computed value along with the store error.

type Manager

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

func NewManager

func NewManager() *Manager

func (*Manager) Clear

func (m *Manager) Clear(ctx context.Context) error

Clear removes all keys and values from the current store. It should not return an error if the store is already empty.

func (*Manager) Delete

func (m *Manager) Delete(ctx context.Context, key string) error

Delete removes a single entry by key. If the key does not exist, it should return nil (no error).

func (*Manager) DeleteByPattern

func (m *Manager) DeleteByPattern(ctx context.Context, pattern string) error

DeleteByPattern removes all keys matching the provided pattern. The pattern syntax depends on the underlying driver (e.g. glob for Redis, regex for memory). Drivers should document their behavior.

func (*Manager) DeleteMany

func (m *Manager) DeleteMany(ctx context.Context, keys ...string) error

DeleteMany removes multiple entries by their keys. If some keys do not exist, they are skipped without returning an error.

func (*Manager) DeleteManyByPattern

func (m *Manager) DeleteManyByPattern(ctx context.Context, patterns ...string) error

DeleteManyByPattern removes entries matching any of the given patterns. Behavior follows DeleteByPattern for each pattern.

func (*Manager) Get

func (m *Manager) Get(ctx context.Context, key string) (any, error)

Get retrieves a raw cached value by key. It returns ErrCacheMiss if the key is not found or has expired.

func (*Manager) GetOrSet

func (m *Manager) GetOrSet(ctx context.Context, key string, ttl time.Duration, defaultFn func() (any, error)) (any, error)

GetOrSet retrieves a value from the cache if present; otherwise, it computes the value lazily by calling defaultFn, stores it with the given TTL, and returns it. If storing fails, it still returns the computed value along with the store error.

func (*Manager) Has

func (m *Manager) Has(ctx context.Context, key string) (bool, error)

Has reports whether the given key exists and is not expired. It should not return an error if the key simply doesn't exist.

func (*Manager) Register

func (m *Manager) Register(alias string, store contract.Store) error

Register adds a new store with the given alias. The first registered store becomes the default. Returns an error if the alias is already registered.

func (*Manager) Set

func (m *Manager) Set(ctx context.Context, key string, value any, ttl time.Duration) error

Set stores a value in the cache under the given key with the specified TTL. A ttl <= 0 should be treated as "no expiration" by convention, but this behavior is driver-dependent.

func (*Manager) SetDefault

func (m *Manager) SetDefault(alias string) error

SetDefault sets the store with the given alias as the default store. Returns an error if the alias has not been registered.

func (*Manager) Store

func (m *Manager) Store(alias string) *Manager

Store switches the active cache store to the one registered under the given alias. It returns a new Manager instance bound to that store. If the alias does not exist, the implementation may return a no-op manager or panic, depending on configuration.

Directories

Path Synopsis
drivers
internal

Jump to

Keyboard shortcuts

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