Smarter approach to the cookies (#103)

* Smarter approach to the cookies

  - Single maxCookieSize = 1400 constant with clear documentation
  - Combined cookie storage for ~40-45% size reduction
  - Backward compatible migration from legacy cookies

* Tuneup the code.
This commit is contained in:
2025-12-12 18:35:06 +00:00
committed by GitHub
parent d0b920c4f0
commit 6efb78b7a8
90 changed files with 1529 additions and 1589 deletions
+8 -14
View File
@@ -34,21 +34,15 @@ type Logger interface {
// for all recovery mechanism implementations. It handles request counting,
// success/failure tracking, and timestamp management in a thread-safe manner.
type BaseRecoveryMechanism struct {
// name identifies the recovery mechanism instance
name string
// logger provides structured logging capabilities
logger Logger
// Metrics tracked with atomic operations for thread safety
logger Logger
name string
lastSuccessStr string
lastFailureStr string
totalRequests int64
successCount int64
failureCount int64
lastSuccessStr string
lastFailureStr string
// mutexes for thread-safe timestamp updates
successMutex sync.RWMutex
failureMutex sync.RWMutex
successMutex sync.RWMutex
failureMutex sync.RWMutex
}
// NewBaseRecoveryMechanism creates a new base recovery mechanism with the given name and logger.
@@ -182,10 +176,10 @@ const (
// HTTPError represents an HTTP error with status code and message
type HTTPError struct {
StatusCode int
Headers map[string]string
Message string
Body []byte
Headers map[string]string
StatusCode int
}
// Error implements the error interface
+7 -13
View File
@@ -60,20 +60,14 @@ func DefaultCircuitBreakerConfig() CircuitBreakerConfig {
// CircuitBreaker implements the circuit breaker pattern for fault tolerance.
// It prevents cascading failures by temporarily blocking requests to a failing service.
type CircuitBreaker struct {
*BaseRecoveryMechanism
config CircuitBreakerConfig
// State management
state int32 // atomic: CircuitBreakerState
lastStateChange time.Time
stateMutex sync.RWMutex
// Failure tracking
consecutiveFailures int32 // atomic
consecutiveSuccesses int32 // atomic
// Half-open state management
halfOpenRequests int32 // atomic
*BaseRecoveryMechanism
config CircuitBreakerConfig
stateMutex sync.RWMutex
state int32
consecutiveFailures int32
consecutiveSuccesses int32
halfOpenRequests int32
}
// NewCircuitBreaker creates a new circuit breaker with the given configuration
+8 -17
View File
@@ -15,20 +15,13 @@ import (
// RetryConfig defines configuration for the retry executor
type RetryConfig struct {
// MaxAttempts is the maximum number of retry attempts
MaxAttempts int
// InitialDelay is the initial delay between retries
InitialDelay time.Duration
// MaxDelay is the maximum delay between retries
MaxDelay time.Duration
// Multiplier is the backoff multiplier
Multiplier float64
// RandomizationFactor adds jitter to delays (0.0 to 1.0)
RandomizationFactor float64
// RetryableErrors defines which errors should trigger a retry
RetryableErrors []string
// RetryableStatusCodes defines which HTTP status codes should trigger a retry
RetryableErrors []string
RetryableStatusCodes []int
MaxAttempts int
InitialDelay time.Duration
MaxDelay time.Duration
Multiplier float64
RandomizationFactor float64
}
// DefaultRetryConfig returns sensible default retry configuration
@@ -46,13 +39,11 @@ func DefaultRetryConfig() RetryConfig {
// RetryExecutor implements retry logic with exponential backoff
type RetryExecutor struct {
lastRetryTime time.Time
*BaseRecoveryMechanism
config RetryConfig
// Metrics
config RetryConfig
totalRetries int64
maxRetriesHit int64
lastRetryTime time.Time
retryTimeMutex sync.RWMutex
}
+8 -8
View File
@@ -273,17 +273,17 @@ func TestRetryExecutor_isRetryableError(t *testing.T) {
executor := NewRetryExecutor(config, logger)
tests := []struct {
name string
err error
name string
expected bool
}{
{"nil error", nil, false},
{"connection refused", errors.New("connection refused"), true},
{"timeout", errors.New("TIMEOUT"), true}, // case insensitive
{"EOF", errors.New("EOF"), false},
{"random error", errors.New("something else"), false},
{"context cancelled", context.Canceled, false},
{"context deadline exceeded", context.DeadlineExceeded, false},
{name: "nil error", err: nil, expected: false},
{name: "connection refused", err: errors.New("connection refused"), expected: true},
{name: "timeout", err: errors.New("TIMEOUT"), expected: true}, // case insensitive
{name: "EOF", err: errors.New("EOF"), expected: false},
{name: "random error", err: errors.New("something else"), expected: false},
{name: "context cancelled", err: context.Canceled, expected: false},
{name: "context deadline exceeded", err: context.DeadlineExceeded, expected: false},
}
for _, tt := range tests {
+6 -6
View File
@@ -13,10 +13,10 @@ import (
// Mock logger for testing
type mockLogger struct {
mu sync.Mutex
logs []string
errLogs []string
debugLog []string
mu sync.Mutex
}
func (m *mockLogger) Logf(format string, args ...interface{}) {
@@ -202,13 +202,13 @@ func TestBaseRecoveryMechanism_ConcurrentAccess(t *testing.T) {
// CircuitBreakerState tests
func TestCircuitBreakerState_String(t *testing.T) {
tests := []struct {
state CircuitBreakerState
expected string
state CircuitBreakerState
}{
{CircuitBreakerClosed, "closed"},
{CircuitBreakerOpen, "open"},
{CircuitBreakerHalfOpen, "half-open"},
{CircuitBreakerState(99), "unknown"},
{state: CircuitBreakerClosed, expected: "closed"},
{state: CircuitBreakerOpen, expected: "open"},
{state: CircuitBreakerHalfOpen, expected: "half-open"},
{state: CircuitBreakerState(99), expected: "unknown"},
}
for _, tt := range tests {