Class: Tasker::CacheStrategy

Inherits:
Object
  • Object
show all
Includes:
Tasker::Concerns::StructuredLogging
Defined in:
lib/tasker/cache_strategy.rb

Overview

Unified cache capability detection and strategy management

This class consolidates cache store introspection from MetricsBackend and IntelligentCacheManager into a single, comprehensive system that:

  1. Detects capabilities of all major Rails cache stores
  2. Supports Solid Cache and other modern Rails cache stores
  3. Provides extensibility for custom cache implementations
  4. Offers a consistent API for cache strategy selection

Phase 2.1.1 Enhancement: Hybrid Cache Store Detection System Combines frozen constants for built-in Rails cache stores with declared capabilities for custom cache stores, creating a robust and extensible architecture.

Detection Priority Order:

  1. Declared capabilities (highest priority) - explicit developer declarations
  2. Built-in store constants - fast, reliable detection for known stores
  3. Custom detectors - pattern-based registration for legacy compatibility
  4. Runtime detection - conservative fallback for unknown stores

Examples:

Basic usage

strategy = Tasker::CacheStrategy.detect
strategy.coordination_mode  # => :distributed_atomic
strategy.supports?(:locking) # => true

Custom detector registration

Tasker::CacheStrategy.register_detector(/MyCache/, ->(store) {
  { distributed: true, custom_feature: true }
})

Custom cache store with capabilities

class MyAwesomeCacheStore < ActiveSupport::Cache::Store
  include Tasker::CacheCapabilities
  supports_distributed_caching!
  supports_atomic_increment!
end

# Configure Rails to use your custom store
Rails.application.configure do
  config.cache_store = MyAwesomeCacheStore.new
end

Direct instantiation

strategy = Tasker::CacheStrategy.new

Constant Summary collapse

COORDINATION_STRATEGIES =

Cache store coordination strategies

{
  distributed_atomic: 'Full distributed coordination with atomic operations',
  distributed_basic: 'Basic distributed coordination with read-modify-write',
  local_only: 'Local-only coordination for single-process deployments'
}.freeze
DISTRIBUTED_CACHE_STORES =

✅ CONSTANTS: Official Rails cache store class names (validated against Rails 8.0+ docs) These provide O(1) lookup performance for built-in Rails cache stores

%w[
  ActiveSupport::Cache::RedisCacheStore
  ActiveSupport::Cache::MemCacheStore
  SolidCache::Store
].freeze
ATOMIC_INCREMENT_STORES =
%w[
  ActiveSupport::Cache::RedisCacheStore
  ActiveSupport::Cache::MemCacheStore
  SolidCache::Store
].freeze
LOCKING_CAPABLE_STORES =
%w[
  ActiveSupport::Cache::RedisCacheStore
  SolidCache::Store
].freeze
LOCAL_CACHE_STORES =
%w[
  ActiveSupport::Cache::MemoryStore
  ActiveSupport::Cache::FileStore
  ActiveSupport::Cache::NullStore
].freeze

Constants included from Tasker::Concerns::StructuredLogging

Tasker::Concerns::StructuredLogging::CORRELATION_ID_KEY

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Tasker::Concerns::StructuredLogging

#correlation_id, #correlation_id=, #log_exception, #log_orchestration_event, #log_performance_event, #log_step_event, #log_structured, #log_task_event, #with_correlation_id

Constructor Details

#initializeCacheStrategy

Create a strategy for the current Rails.cache store

The cache strategy always analyzes Rails.cache, which is the single source of truth for caching in Rails applications. Custom cache stores should be configured through Rails.cache and declare their capabilities via the CacheCapabilities module.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/tasker/cache_strategy.rb', line 114

def initialize
  @detector_registry = DetectorRegistry.instance
  @instance_id = generate_instance_id

  # Handle Rails.cache unavailability gracefully
  begin
    @store = Rails.cache
    @store_class_name = @store.class.name
  rescue StandardError => e
    log_structured(:warn, 'Rails.cache unavailable, using fallback configuration',
                   error: e.message,
                   instance_id: @instance_id)
    @store = nil
    @store_class_name = 'Unknown'
    @capabilities = default_capabilities
    @coordination_mode = :local_only
    return
  end

  # Generate cache key that includes store configuration
  cache_key = generate_cache_key(@store, @store_class_name)

  # Check for cached strategy first
  cached = @detector_registry.cached_strategy_for(cache_key)
  if cached
    @capabilities = cached.capabilities
    @coordination_mode = cached.coordination_mode
  else
    # Detect capabilities with error handling
    begin
      @capabilities = detect_capabilities
      @coordination_mode = select_coordination_strategy

      # Cache this strategy instance
      @detector_registry.cache_strategy_for(cache_key, self)
    rescue StandardError => e
      log_structured(:warn, 'Cache detection failed',
                     error: e.message,
                     store_class: @store_class_name,
                     instance_id: @instance_id)
      log_structured(:warn, 'Falling back to local-only mode')
      @store_class_name = 'Unknown'
      @capabilities = default_capabilities
      @coordination_mode = :local_only
      return
    end
  end

  log_strategy_detection
end

Instance Attribute Details

#capabilitiesObject (readonly)

Returns the value of attribute capabilities.



86
87
88
# File 'lib/tasker/cache_strategy.rb', line 86

def capabilities
  @capabilities
end

#coordination_modeObject (readonly)

Returns the value of attribute coordination_mode.



86
87
88
# File 'lib/tasker/cache_strategy.rb', line 86

def coordination_mode
  @coordination_mode
end

#instance_idObject (readonly)

Returns the value of attribute instance_id.



86
87
88
# File 'lib/tasker/cache_strategy.rb', line 86

def instance_id
  @instance_id
end

#storeObject (readonly)

Returns the value of attribute store.



86
87
88
# File 'lib/tasker/cache_strategy.rb', line 86

def store
  @store
end

#store_class_nameObject (readonly)

Returns the value of attribute store_class_name.



86
87
88
# File 'lib/tasker/cache_strategy.rb', line 86

def store_class_name
  @store_class_name
end

Class Method Details

.clear_detectors!Object

Clear all registered detectors (primarily for testing)



104
105
106
# File 'lib/tasker/cache_strategy.rb', line 104

def self.clear_detectors!
  DetectorRegistry.instance.clear_detectors!
end

.detectTasker::CacheStrategy

Detect cache strategy for the current Rails.cache store

Returns:



91
92
93
# File 'lib/tasker/cache_strategy.rb', line 91

def self.detect
  new
end

.register_detector(pattern, detector) ⇒ Object

Register a custom cache store detector

Parameters:

  • pattern (Regexp, String)

    Pattern to match store class names

  • detector (Proc)

    Detector that returns capabilities hash



99
100
101
# File 'lib/tasker/cache_strategy.rb', line 99

def self.register_detector(pattern, detector)
  DetectorRegistry.instance.register_detector(pattern, detector)
end

Instance Method Details

#export_capabilitiesHash

Export capabilities for backward compatibility

Returns:

  • (Hash)

    Hash of capabilities for legacy integrations



176
177
178
# File 'lib/tasker/cache_strategy.rb', line 176

def export_capabilities
  @capabilities.dup
end

#supports?(capability) ⇒ Boolean

Check if store supports a specific capability

Parameters:

  • capability (Symbol)

    Capability to check (:distributed, :atomic_increment, etc.)

Returns:

  • (Boolean)

    True if capability is supported



169
170
171
# File 'lib/tasker/cache_strategy.rb', line 169

def supports?(capability)
  @capabilities[capability] || false
end