ctxcache

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

README

ctxcache

English | 中文

Introduction

ctxcache is a strongly-typed, context-scoped cache package designed for request-scoped data.

ctxcache attaches a concurrency-safe, write-once key-value store to context.Context, allowing values to be implicitly propagated across call boundaries without polluting function signatures.

Features

  • Strong Type Safety: Uses generics combining string names and Go type parameters as key identifiers, ensuring type safety and preventing collisions between values of different types—even if they share the same string identifier
  • Concurrency Safe: Internally uses mutex-protected maps, supporting concurrent access
  • Write-Once Semantics: Each key can be assigned exactly once, then read multiple times until the cache is cleared
  • Context Lifecycle: Cache lifecycle is explicitly controlled by the cancel function returned from Init
  • Request Scope Isolation: Cache is attached to context, naturally supporting request-level data isolation

Main Functions

Initialize Cache

Use the Init function to attach a cache to a context:

ctx, cancel := ctxcache.Init(ctx)
defer cancel() // Clean up cache at request boundary

Init is idempotent: repeated calls with the same context return the original context and a no-op cancel function.

Set Values

Use the Set function to assign a value to a key:

err := ctxcache.Set(ctx, "user", userInfo)
if err != nil {
// handle error
}

Each key can only be set once. Repeated attempts return an ErrKeyAlreadySet error.

Get Values

Use the Get function to retrieve a value:

value, err := ctxcache.Get[UserType](ctx, "user")
if err != nil {
// handle error
}

Get is a generic function that requires specifying a type parameter to ensure type safety.

Clear Cache

Calling the cancel function returned by Init clears all cached values:

cancel() // Clear cache and make it permanently unusable

Once cleared, subsequent Get or Set operations will return ErrCacheAlreadyCleared error.

Error Types

The package defines the following error types:

  • ErrCacheNotInitialized: Cache is not initialized
  • ErrCacheAlreadyCleared: Cache has already been cleared
  • ErrKeyNotSet: Key is not set
  • ErrKeyAlreadySet: Key is already set

Typical Use Cases

  1. HTTP Middleware: Initialize cache at request entry point and clean up at exit
  2. Authenticated User Info: Store authenticated user objects
  3. Permission Data: Pass user permission lists
  4. Trace Metadata: Carry trace context information
  5. Computed Intermediates: Share computed intermediate values across call chains

Example Usage

package main

import (
	"context"
	"fmt"
	"github.com/go-spring/stdlib/ctxcache"
)

type User struct {
	ID   int
	Name string
}

func main() {
	ctx := context.Background()

	// Initialize cache
	ctx, cancel := ctxcache.Init(ctx)
	defer cancel()

	// Set user info
	user := User{ID: 1, Name: "Alice"}
	if err := ctxcache.Set(ctx, "user", user); err != nil {
		panic(err)
	}

	// Get user info in downstream code
	retrievedUser, err := ctxcache.Get[User](ctx, "user")
	if err != nil {
		panic(err)
	}

	fmt.Printf("User: %+v\n", retrievedUser)
}

Notes

  • ctxcache is not a general-purpose cache. It is designed for structured, short-lived, in-process context data
  • Each key can only be assigned once. This is intentional design to ensure data immutability
  • The cancel function should be called at request boundaries to ensure request-scoped data is properly cleaned up
  • Once cleared, the cache becomes permanently unusable and should not be used again

Documentation

Overview

Package ctxcache provides a strongly-typed, context-scoped cache for request-scoped data.

ctxcache attaches a concurrency-safe, write-once key–value store to a context.Context, allowing values to be implicitly propagated across call boundaries without polluting function signatures.

Keys are identified by a combination of a string name and a Go type via generics, ensuring type safety and preventing collisions between values of different types—even if they share the same string identifier.

Each key may be assigned exactly once. After a value is set, it can be retrieved multiple times until the cache is cleared.

The cache lifecycle is explicitly controlled by a cancel function returned by Init. When the cancel function is called, all cached values are removed and the cache becomes permanently unusable.

ctxcache is not a general-purpose cache. It is designed for structured, short-lived, in-process data bound to a context's lifetime, such as authenticated users, permissions, trace metadata, or computed intermediates.

Typical usage:

  1. Initialize the cache at the request boundary (e.g. HTTP middleware).
  2. Set each value at most once using Set.
  3. Retrieve values using Get in downstream code.
  4. Defer the cancel function returned by Init to clean up request-scoped data.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCacheNotInitialized = errutil.Explain(nil, "cache not initialized")
	ErrCacheAlreadyCleared = errutil.Explain(nil, "cache already cleared")
	ErrKeyNotSet           = errutil.Explain(nil, "key not set")
	ErrKeyAlreadySet       = errutil.Explain(nil, "key already set")
)

Functions

func Get

func Get[T any](ctx context.Context, key string) (T, error)

Get retrieves the value associated with the given key.

Returns an error if:

  • the cache is not initialized,
  • the cache has already been cleared, or
  • no value has been set for the given key.

func Init

func Init(ctx context.Context) (_ context.Context, cancel func())

Init attaches a Cache to the given context and returns the new context along with a cancel function.

Only one Cache may be attached to a context. Repeated calls to Init with the same context are safe: if a Cache already exists, Init returns the original context and a no-op cancel function.

The returned cancel function should typically be deferred at the request boundary (e.g. in HTTP middleware) to ensure request-scoped data is cleaned up.

When a Cache is newly created, the cancel function clears the Cache. Calling the cancel function multiple times is safe.

func Set

func Set[T any](ctx context.Context, key string, value T) error

Set assigns a value to the given key.

Each key may be assigned exactly once. Subsequent attempts to set the same key return ErrKeyAlreadySet.

Returns an error if:

  • the cache is not initialized, or
  • the cache has already been cleared.

Types

type Cache

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

Cache holds context-scoped data associated with a context.Context.

Internally, Cache maintains a mutex-protected map keyed by strongly typed keys. The cache is propagated through the context without appearing in function signatures, making it suitable for passing data across modules.

A Cache is write-once per key: each key may be assigned a value exactly once. Values can be read multiple times until the cache is cleared.

Once cleared, the cache becomes permanently unusable; subsequent Get or Set operations will return ErrCacheAlreadyCleared.

func (*Cache) Clear

func (cache *Cache) Clear()

Clear removes all cached values and marks the cache as cleared.

Clear is idempotent. Only the first call performs cleanup; subsequent calls have no effect.

After Clear is called, the cache is permanently unusable. All future Get or Set operations will return ErrCacheAlreadyCleared.

type TypedKey

type TypedKey[T any] struct {
	Key string
}

TypedKey represents a strongly typed cache key.

A TypedKey is defined by a string identifier and a Go type parameter. Keys with the same string but different type parameters are considered distinct and do not collide.

func (TypedKey[T]) String

func (k TypedKey[T]) String() string

Jump to

Keyboard shortcuts

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