Skip to content

Releases: 1mb-dev/obcache-go

v2.0.0 - Major Simplification & Breaking Changes

28 Oct 16:01

Choose a tag to compare

Major Simplification & Breaking Changes

This release significantly simplifies the codebase by removing over-engineered abstractions and consolidating implementations. Net reduction: 3,057 lines of code (-92%).

⚠️ BREAKING CHANGES

Memory Store Consolidation

Changed:

  • Removed dual memory store implementations
  • Unified on StrategyStore for all eviction strategies (LRU/LFU/FIFO)
  • Strategy.Add() signature changed to return evicted entry:
    // Before
    Add(key string, entry *entry.Entry) (evictKey string, evicted bool)
    
    // After
    Add(key string, entry *entry.Entry) (evictKey string, evictedEntry *entry.Entry, evicted bool)

Impact:

  • Only affects custom Strategy implementations (internal API)
  • Eviction callbacks now receive actual evicted values instead of placeholders
  • Better observability for eviction events

Metrics System Changes

Removed:

  • OpenTelemetry support completely removed
  • pkg/metrics/opentelemetry.go deleted (351 lines)
  • All OpenTelemetry dependencies removed from go.mod

Kept:

  • Prometheus metrics exporter (fully functional)
  • metrics.Exporter interface for custom implementations
  • All existing Prometheus integrations work unchanged

Migration Path:

// If you were using OpenTelemetry, switch to Prometheus:
promConfig := &metrics.PrometheusConfig{
    Registry: prometheus.DefaultRegisterer,
}
exporter, _ := metrics.NewPrometheusExporter(metricsConfig, promConfig)

// Or implement custom exporter:
type CustomExporter struct{}
func (e *CustomExporter) ExportStats(stats metrics.Stats, labels metrics.Labels) error {
    // Your implementation
}

Examples Consolidation

Removed Examples (6):

  • advanced - Used deprecated hooks API
  • batch-processing - Too specific/niche
  • debug - Utility, not core feature
  • echo-web-server - Redundant with Gin
  • opentelemetry - OpenTelemetry removed
  • metrics - Used OpenTelemetry

Kept & Updated (5 core examples):

  • basic - Getting started
  • compression - Data compression feature
  • redis-cache - Redis backend integration
  • prometheus - Metrics with Prometheus
  • gin-web-server - Web framework integration

All examples updated to use context-aware hooks API.

Improvements

Code Quality:

  • Removed 3,057 lines of redundant code
  • Single, well-tested memory store implementation
  • Cleaner dependency tree (no OpenTelemetry deps)
  • Better eviction callback semantics
  • More focused, maintainable examples

Documentation:

  • Updated all package documentation
  • Fixed outdated API examples
  • Added eviction strategy documentation
  • Clarified metrics integration options

Performance:

  • Zero performance regressions
  • Eviction callbacks more efficient (no goroutine spawn)
  • Reduced memory allocations in hot paths

Testing

  • ✅ All tests pass with -race detector
  • ✅ Zero test regressions
  • ✅ All 5 examples build successfully
  • ✅ Coverage improved to ~48%

Migration Guide

For Strategy Implementers:
If you implemented a custom eviction strategy, update the Add() method:

func (s *CustomStrategy) Add(key string, entry *entry.Entry) (string, *entry.Entry, bool) {
    // Capture evicted entry before deletion
    if needsEviction {
        evictedEntry := s.data[evictKey]
        delete(s.data, evictKey)
        return evictKey, evictedEntry, true
    }
    return "", nil, false
}

For OpenTelemetry Users:
Switch to Prometheus or implement the metrics.Exporter interface for your preferred backend.

For Example Users:
Review the 5 core examples - they demonstrate all key features with updated APIs.


Full Changelog: https://github.com/vnykmshr/obcache-go/blob/main/CHANGELOG.md

v1.1.0 - Context Support & Reliability Improvements

27 Oct 05:21

Choose a tag to compare

🎉 What's New in v1.1.0

This release adds context propagation support for better observability, fixes a critical goroutine leak, and updates dependencies.

✨ New Features

Context Propagation Support

  • New APIs: GetContext() and SetContext() methods for context-aware operations
  • Better Observability: Proper timeout and cancellation propagation
  • Distributed Tracing: Context support throughout cache operations and hooks
  • Function Wrapping: Context propagation in Wrap() for instrumented functions
  • Backward Compatible: Existing Get()/Set() methods unchanged
// New: Context-aware operations with timeouts
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

value, found := cache.GetContext(ctx, "key")
err := cache.SetContext(ctx, "key", value, time.Minute)

// Works with wrapped functions too
cachedFunc := obcache.Wrap(cache, expensiveFunc)
result, err := cachedFunc(ctx, arg) // Context propagated!

🐛 Bug Fixes

Critical Goroutine Leak Fixed

  • Fixed unbounded goroutine spawning in memory store expired entry cleanup
  • Replaced async cleanup with synchronous lock upgrade pattern
  • Prevents resource exhaustion under high load with expired entries
  • Impact: Significantly improves stability for long-running applications

Location: internal/store/memory/memory.go:58-90

📦 Dependency Updates

Redis Client Major Update

  • Upgraded from v9.6.3v9.16.0 (10 minor versions)
  • Includes maintenance notification support
  • Trace filtering improvements
  • Numerous bug fixes and performance enhancements

Compatibility

  • All dependencies compatible with Go 1.23+
  • Transitive dependencies updated for stability

🔧 CI/CD Improvements

New Quality Gates

  • ✅ Example build validation (prevents broken docs)
  • ✅ Coverage threshold enforcement (45% minimum)
  • ✅ Automated example compilation checks
  • ✅ Improved CI reliability

📊 Testing & Validation

  • 100+ tests passing with race detector
  • Zero breaking changes - fully backward compatible
  • Coverage: Maintained at 47%+ across core packages
  • Validated: All examples compile and run correctly

🔄 Migration Guide

No Breaking Changes - Drop-in replacement for v1.0.x

To adopt new context features:

// Before
value, found := cache.Get(key)
cache.Set(key, value, ttl)

// After (with context)
value, found := cache.GetContext(ctx, key)
cache.SetContext(ctx, key, value, ttl)

📝 Full Changelog

See CHANGELOG.md for detailed changes.

🙏 Credits

  • Dependency updates via Dependabot
  • CI improvements and code quality enhancements
  • Community feedback and testing

Installation:

go get github.com/vnykmshr/[email protected]

Documentation: https://github.com/vnykmshr/obcache-go
Issues: https://github.com/vnykmshr/obcache-go/issues

v1.0.3 - Production Ready Code Quality Release

16 Sep 14:28

Choose a tag to compare

🚀 v1.0.3 - Production Ready Code Quality Release

This release focuses on code quality, maintainability, and production readiness with comprehensive cleanup and standardization.

Key Improvements

🧹 Code Quality & Cleanup

  • Removed development artifacts - Cleaned up 12MB binary and development directories
  • Centralized test constants - New testutil.go with standardized test values
  • Standardized formatting - Consistent code style across entire codebase
  • Fixed all lint issues - Clean static analysis with no warnings
  • Improved struct alignment - Better memory layout and readability

🔧 Technical Enhancements

  • Test Constants: Added TestTTL, TestSlowOperation, TestMetricsReportInterval
  • Dependency cleanup: Optimized go.sum and module management
  • Code consistency: Unified indentation and formatting standards
  • Professional polish: Code now reads as enterprise-grade library

📊 Quality Metrics

  • All tests passing - Complete test suite with 100% success rate
  • Clean builds - go build ./... completes without errors or warnings
  • No vet issues - Static analysis passes cleanly
  • Production ready - Suitable for enterprise deployment

🎯 What This Means

This release transforms obcache-go from a functional library into a professional, production-ready Go package with:

  • Enterprise-grade code quality suitable for critical production systems
  • Improved maintainability for future development and contributions
  • Consistent developer experience across all examples and tests
  • Clean, readable codebase that follows Go best practices

📦 Installation

go get github.com/vnykmshr/[email protected]

🔄 Upgrade Notes

This release is 100% backward compatible - no breaking changes to the public API. Existing code will work without modifications.


Full Changelog: v1.0.2...v1.0.3

obcache-go v1.0.2 - High-Performance Go Caching Library

31 Aug 08:54

Choose a tag to compare

What's Changed

  • Bump golangci/golangci-lint-action from 6 to 8 by @dependabot[bot] in #1
  • Bump actions/checkout from 4 to 5 by @dependabot[bot] in #2
  • Bump codecov/codecov-action from 4 to 5 by @dependabot[bot] in #3

New Contributors

Full Changelog: v1.0.0...v1.0.2

obcache-go v1.0.1 - High-Performance Go Caching Library

29 Aug 17:17

Choose a tag to compare

obcache-go v1.0.0 - High-Performance Go Caching Library

27 Aug 08:10

Choose a tag to compare

obcache-go v1.0.0 Release Notes

🎉 Initial stable release of obcache-go - A high-performance, thread-safe caching library for Go.

🚀 What is obcache-go?

obcache-go is a powerful caching library designed for modern Go applications. It provides automatic function wrapping, multiple backend support, and production-ready features that make caching both simple and powerful.

✨ Key Features

🎯 Function Wrapping (Primary Feature)

// Turn any function into a cached version
cachedFunc := obcache.Wrap(cache, expensiveFunction)
result, _ := cachedFunc(args...) // Automatic caching!

🏪 Multiple Backends

  • Memory: High-performance in-memory caching
  • Redis: Distributed caching for multi-instance deployments

🔧 Advanced Features

  • TTL Support: Time-based expiration with automatic cleanup
  • LRU/LFU/FIFO Eviction: Multiple eviction strategies
  • Compression: Gzip/Deflate compression for large values
  • Thread Safety: Optimized concurrent access
  • Statistics: Hit rates, miss counts, performance metrics
  • Hooks: Event callbacks for monitoring and debugging
  • Singleflight: Prevents duplicate concurrent function calls

📊 Monitoring & Observability

  • Prometheus metrics integration
  • OpenTelemetry support
  • Built-in statistics and hit rate tracking
  • Event hooks for custom monitoring

🎯 Why Choose obcache-go?

  1. Simplicity: One line to cache any function - obcache.Wrap(cache, fn)
  2. Performance: Optimized for high-concurrency scenarios
  3. Flexibility: Memory or Redis backends, multiple eviction strategies
  4. Production Ready: Comprehensive testing, monitoring, and error handling
  5. Type Safety: Full Go generics support for type-safe caching

📚 Quick Start

package main

import (
    "fmt"
    "time"
    "github.com/vnykmshr/obcache-go/pkg/obcache"
)

func expensiveFunction(id int) (string, error) {
    time.Sleep(100 * time.Millisecond) // Simulate work
    return fmt.Sprintf("result-%d", id), nil
}

func main() {
    cache, _ := obcache.New(obcache.NewDefaultConfig())
    
    // Wrap function with caching
    cachedFunc := obcache.Wrap(cache, expensiveFunction)
    
    // First call: slow (cache miss)
    result1, _ := cachedFunc(123) 
    
    // Second call: fast (cache hit)  
    result2, _ := cachedFunc(123)
    
    fmt.Println(result1, result2) // Same result, much faster
}

📦 Installation

go get github.com/vnykmshr/obcache-go

Requires Go 1.21+ for generics support.

🎨 Configuration Examples

Memory Cache

config := obcache.NewDefaultConfig().
    WithMaxEntries(1000).
    WithDefaultTTL(30 * time.Minute)
cache, _ := obcache.New(config)

Redis Cache

config := obcache.NewRedisConfig("localhost:6379").
    WithRedis(&obcache.RedisConfig{KeyPrefix: "myapp:"})
cache, _ := obcache.New(config)

With Compression

config := obcache.NewDefaultConfig().
    WithCompression(&compression.Config{
        Enabled: true,
        Algorithm: compression.CompressorGzip,
        MinSize: 1000, // Only compress values > 1KB
    })

📈 Performance

  • Concurrent reads/writes: Optimized locking strategy
  • Memory efficient: LRU eviction prevents unbounded growth
  • Fast key generation: Efficient hashing for complex keys
  • Singleflight: Eliminates duplicate work under high load

🧪 Examples

The release includes comprehensive examples:

🔄 Migration from other libraries

From go-cache:

// Before (go-cache)
import "github.com/patrickmn/go-cache"
c := cache.New(5*time.Minute, 10*time.Minute)

// After (obcache-go)  
import "github.com/vnykmshr/obcache-go/pkg/obcache"
cache, _ := obcache.New(obcache.NewDefaultConfig())

🎯 Best Practices

  1. Use function wrapping - More convenient than manual cache operations
  2. Set appropriate TTLs - Balance freshness vs performance
  3. Monitor hit rates - Aim for >80% hit rate for good effectiveness
  4. Use Redis for distributed scenarios - Essential for multi-instance apps
  5. Enable compression - For large values (>1KB) to save memory

🔗 Links

🙏 Acknowledgments

This library was built with production use cases in mind, incorporating lessons learned from scaling Go applications. Special thanks to the Go community for the excellent ecosystem of tools and libraries that made this possible.


Ready to supercharge your Go applications with intelligent caching?

go get github.com/vnykmshr/obcache-go

Happy caching! 🚀