Documentation
¶
Index ¶
- type InMemoryCache
- func (c *InMemoryCache) Delete(_ context.Context, keys ...string) error
- func (c *InMemoryCache) Get(_ context.Context, key string) (UserRepositoryCachedResult, bool)
- func (c *InMemoryCache) Set(_ context.Context, key string, value any, ttl time.Duration) error
- func (c *InMemoryCache) SetError(_ context.Context, key string, err error, ttl time.Duration) (bool, error)
- type Order
- type OrderRepository
- type OrderRepositoryDelegator
- type OrderRepositoryDelegatorFunc
- type User
- type UserRepository
- type UserRepositoryCache
- type UserRepositoryCacheAsyncExecutor
- type UserRepositoryCacheLocker
- type UserRepositoryCachedResult
- type UserRepositoryDelegator
- func (d *UserRepositoryDelegator) Build() UserRepository
- func (d *UserRepositoryDelegator) Use(mw UserRepositoryDelegatorFunc) *UserRepositoryDelegator
- func (d *UserRepositoryDelegator) WithCache(cache UserRepositoryCache) *UserRepositoryDelegator
- func (d *UserRepositoryDelegator) WithTracing(tracer trace.Tracer) *UserRepositoryDelegator
- type UserRepositoryDelegatorFunc
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type InMemoryCache ¶
type InMemoryCache struct {
// contains filtered or unexported fields
}
InMemoryCache is a simple in-memory cache implementation for demonstration.
func NewInMemoryCache ¶
func NewInMemoryCache() *InMemoryCache
NewInMemoryCache creates a new in-memory cache.
func (*InMemoryCache) Delete ¶
func (c *InMemoryCache) Delete(_ context.Context, keys ...string) error
Delete removes keys from the cache.
func (*InMemoryCache) Get ¶
func (c *InMemoryCache) Get(_ context.Context, key string) (UserRepositoryCachedResult, bool)
Get retrieves a cached value.
type OrderRepository ¶
type OrderRepository interface {
// GetByID retrieves an order by ID with tracing only.
// delegatorgen:@trace(name="order.get", attrs=id)
GetByID(ctx context.Context, id string) (*Order, error)
// Create creates a new order.
// delegatorgen:@trace(name="order.create")
Create(ctx context.Context, order *Order) error
}
OrderRepository is a repository interface for Order operations. delegatorgen:@delegator
type OrderRepositoryDelegator ¶
type OrderRepositoryDelegator struct {
// contains filtered or unexported fields
}
OrderRepositoryDelegator builds a OrderRepository with delegators.
func NewOrderRepositoryDelegator ¶
func NewOrderRepositoryDelegator(base OrderRepository) *OrderRepositoryDelegator
NewOrderRepositoryDelegator creates a new delegator builder.
func (*OrderRepositoryDelegator) Build ¶
func (d *OrderRepositoryDelegator) Build() OrderRepository
Build creates the final OrderRepository with all delegators applied. Delegators are applied in reverse order so that the first added delegator is the outermost (executes first).
func (*OrderRepositoryDelegator) Use ¶
func (d *OrderRepositoryDelegator) Use(mw OrderRepositoryDelegatorFunc) *OrderRepositoryDelegator
Use adds a custom delegator. Delegators are applied in order: first added = outermost (executes first).
func (*OrderRepositoryDelegator) WithTracing ¶
func (d *OrderRepositoryDelegator) WithTracing(tracer trace.Tracer) *OrderRepositoryDelegator
WithTracing adds tracing delegator using OpenTelemetry.
type OrderRepositoryDelegatorFunc ¶
type OrderRepositoryDelegatorFunc func(OrderRepository) OrderRepository
OrderRepositoryDelegatorFunc is a function that wraps a OrderRepository.
type UserRepository ¶
type UserRepository interface {
// GetByID retrieves a user by ID.
// Uses cache with 5 minute TTL and tracing.
// delegatorgen:@cache(ttl=5m)
// delegatorgen:@trace(attrs=id)
GetByID(ctx context.Context, id string) (*User, error)
// GetByEmail retrieves a user by email.
// Uses cache with custom key template.
// delegatorgen:@cache(ttl=10m, key="user:email:{email}")
// delegatorgen:@trace
GetByEmail(ctx context.Context, email string) (*User, error)
// List retrieves users with pagination.
// Uses cache with TTL jitter to prevent thundering herd.
// delegatorgen:@cache(ttl=2m, jitter=30s, prefix="users:list")
// delegatorgen:@trace(attrs=offset,limit)
List(ctx context.Context, offset, limit int) ([]*User, error)
// Save creates or updates a user.
// Evicts cache entries for this user.
// delegatorgen:@cache_evict(key="user:id:{user.ID}")
// delegatorgen:@trace
Save(ctx context.Context, user *User) error
// Delete removes a user.
// Evicts cache entries for this user.
// delegatorgen:@cache_evict(key="user:id:{id}")
// delegatorgen:@trace(attrs=id)
Delete(ctx context.Context, id string) error
}
UserRepository is a repository interface for User operations. delegatorgen:@delegator
type UserRepositoryCache ¶
type UserRepositoryCache interface {
// Get retrieves cached result by key.
// Returns the cached result and whether the key was found.
Get(ctx context.Context, key string) (result UserRepositoryCachedResult, ok bool)
// Set stores a value with the given TTL.
Set(ctx context.Context, key string, value any, ttl time.Duration) error
// SetError decides whether to cache an error and stores it if needed.
// Returns shouldCache=true if the error was cached.
SetError(ctx context.Context, key string, err error, ttl time.Duration) (shouldCache bool, cacheErr error)
// Delete removes one or more keys from the cache.
Delete(ctx context.Context, keys ...string) error
}
UserRepositoryCache is a generic caching interface. Implement this interface to integrate with your cache library (e.g., Redis, in-memory).
type UserRepositoryCacheAsyncExecutor ¶
type UserRepositoryCacheAsyncExecutor interface {
// Submit submits a task for async execution.
Submit(task func())
}
UserRepositoryCacheAsyncExecutor is an optional interface for async cache refresh. If your cache implementation also implements this interface, the cache delegator will automatically use it to refresh cache entries in the background.
type UserRepositoryCacheLocker ¶
type UserRepositoryCacheLocker interface {
// Lock acquires a distributed lock for the given key.
// Returns a release function and whether the lock was acquired.
Lock(ctx context.Context, key string) (release func(), acquired bool)
}
UserRepositoryCacheLocker is an optional interface for distributed locking. If your cache implementation also implements this interface, the cache delegator will automatically use it to prevent cache stampede.
type UserRepositoryCachedResult ¶
type UserRepositoryCachedResult interface {
// Value returns the cached data.
// If IsError() returns true, this returns the cached error.
Value() any
// ExpiresAt returns the expiration time (used for async refresh decision).
ExpiresAt() time.Time
// IsError returns true if this is an error cache entry (for cache penetration prevention).
IsError() bool
}
UserRepositoryCachedResult represents a cached value with metadata. Users must implement this interface to integrate with their cache library.
type UserRepositoryDelegator ¶
type UserRepositoryDelegator struct {
// contains filtered or unexported fields
}
UserRepositoryDelegator builds a UserRepository with delegators.
Example ¶
ExampleUserRepositoryDelegator demonstrates how to use the generated delegator.
// Create a base repository implementation
baseRepo := &mockUserRepository{}
// Create cache and tracer
cache := NewInMemoryCache()
tracer := otel.Tracer("example")
// Build the delegator with cache and tracing
repo := NewUserRepositoryDelegator(baseRepo).
WithCache(cache).
WithTracing(tracer).
Build()
// Use the repository - caching and tracing are automatic
ctx := context.Background()
// First call - cache miss, calls base repository
user, err := repo.GetByID(ctx, "user-123")
if err != nil {
panic(err)
}
fmt.Printf("Got user: %s\n", user.Name)
// Second call - cache hit, returns cached value
user, err = repo.GetByID(ctx, "user-123")
if err != nil {
panic(err)
}
fmt.Printf("Got user (cached): %s\n", user.Name)
// Save invalidates cache
user.Name = "Updated Name"
if err := repo.Save(ctx, user); err != nil {
panic(err)
}
// Third call - cache miss again due to eviction
user, err = repo.GetByID(ctx, "user-123")
if err != nil {
panic(err)
}
fmt.Printf("Got user (after save): %s\n", user.Name)
func NewUserRepositoryDelegator ¶
func NewUserRepositoryDelegator(base UserRepository) *UserRepositoryDelegator
NewUserRepositoryDelegator creates a new delegator builder.
func (*UserRepositoryDelegator) Build ¶
func (d *UserRepositoryDelegator) Build() UserRepository
Build creates the final UserRepository with all delegators applied. Delegators are applied in reverse order so that the first added delegator is the outermost (executes first).
func (*UserRepositoryDelegator) Use ¶
func (d *UserRepositoryDelegator) Use(mw UserRepositoryDelegatorFunc) *UserRepositoryDelegator
Use adds a custom delegator. Delegators are applied in order: first added = outermost (executes first).
func (*UserRepositoryDelegator) WithCache ¶
func (d *UserRepositoryDelegator) WithCache(cache UserRepositoryCache) *UserRepositoryDelegator
WithCache adds caching delegator. Advanced features (distributed lock, async refresh) are automatically enabled if the cache implementation also implements CacheLocker or CacheAsyncExecutor.
func (*UserRepositoryDelegator) WithTracing ¶
func (d *UserRepositoryDelegator) WithTracing(tracer trace.Tracer) *UserRepositoryDelegator
WithTracing adds tracing delegator using OpenTelemetry.
type UserRepositoryDelegatorFunc ¶
type UserRepositoryDelegatorFunc func(UserRepository) UserRepository
UserRepositoryDelegatorFunc is a function that wraps a UserRepository.