Skip to content

v2.0.0 - Pluggable Store Interface

Choose a tag to compare

@felixgeelhaar felixgeelhaar released this 08 Dec 13:32
· 96 commits to main since this release
8a71aa9

Fortify v2.0.0 - Pluggable Store Interface

This release introduces a major architectural refactor of the rate limiter to use a pluggable Store interface, enabling distributed rate limiting across multiple application instances.

⚠️ Breaking Changes

  • Removed backends/redis module - Users now implement the Store interface for custom backends
  • Removed examples/backends/redis - See migration guide for implementation patterns

✨ New Features

Pluggable Store Interface

type Store interface {
    AtomicUpdate(ctx context.Context, key string, updateFn func(*BucketState) *BucketState) (*BucketState, error)
    Get(ctx context.Context, key string) (*BucketState, error)
    Delete(ctx context.Context, key string) error
    Close() error
}

New Rate Limiter Methods

  • Execute(ctx, key, operation) - Combines rate limiting check with operation execution
  • ExecuteN(ctx, key, tokens, operation) - Multi-token variant for batch operations
  • Reset(ctx) - Clear all rate limiting state (requires Resetter interface)
  • BucketCount() - Monitor active buckets (requires BucketCounter interface)

Optional Interfaces for Extensibility

  • HealthChecker - Health check support for distributed stores
  • Resetter - Reset/clear all buckets
  • BucketCounter - Report active bucket count

Configuration Enhancements

  • FailOpen - Allow requests when storage fails (availability over consistency)
  • MaxTokensPerRequest - Prevent DoS via excessive token requests

📊 Performance (Apple M1, Go 1.23)

Operation Latency Memory Allocations
Allow() ~200ns 74B 3
Take() ~197ns 65B 3
BucketCount() ~3ns 0B 0
Concurrent ~395ns 82B 3

📈 Quality Metrics

  • Test Coverage: 92.3%
  • Race Detection: Clean
  • Security Grade: A+
  • Examples: 16 runnable examples

🔄 Migration Guide

See docs/MIGRATION_REDIS.md for:

  • Custom Redis Store implementation patterns
  • DynamoDB and PostgreSQL examples
  • Migration steps from v1.x

📦 Installation

go get github.com/felixgeelhaar/fortify@v2.0.0

💡 Quick Start

// In-memory (default) - no changes required
rl := ratelimit.New(ratelimit.Config{
    Rate:     100,
    Burst:    200,
    Interval: time.Second,
})

// Custom store for distributed rate limiting
rl := ratelimit.New(ratelimit.Config{
    Rate:     100,
    Burst:    200,
    Interval: time.Second,
    Store:    myRedisStore,  // Implement Store interface
    FailOpen: true,          // Allow on storage failure
})

// New Execute method
err := rl.Execute(ctx, "user-123", func() error {
    return processRequest()
})

🙏 Contributors

Thank you to everyone who contributed to this release!