Class: Appom::ElementCache::Cache
- Inherits:
-
Object
- Object
- Appom::ElementCache::Cache
- Includes:
- Logging
- Defined in:
- lib/appom/element_cache.rb
Overview
Element caching to improve performance for frequently accessed elements
Instance Attribute Summary collapse
-
#max_size ⇒ Object
readonly
Returns the value of attribute max_size.
-
#ttl ⇒ Object
readonly
Returns the value of attribute ttl.
Instance Method Summary collapse
-
#clear ⇒ Object
Clear all cached elements.
- #generate_key(*args) ⇒ Object
-
#get(cache_key) ⇒ Object
Get element from cache by key.
-
#get_or_find(*find_args) ⇒ Object
Get element from cache or find and cache it.
-
#hit?(cache_key) ⇒ Boolean
Check if key exists in cache.
-
#initialize(max_size: 100, ttl: 300) ⇒ Cache
constructor
A new instance of Cache.
-
#invalidate(*find_args) ⇒ Object
Invalidate specific element.
-
#reset ⇒ Object
Clear all cached elements and reset statistics.
-
#size ⇒ Object
Get cache size.
-
#statistics ⇒ Object
Get cache statistics.
-
#stats ⇒ Object
Alias for backward compatibility.
-
#store(strategy, value, element) ⇒ Object
Store element in cache with strategy and value.
-
#valid_element?(element) ⇒ Boolean
Check if element is still valid (exists and is stale).
Methods included from Logging
level, level=, #log_debug, #log_element_action, #log_error, #log_info, #log_wait_end, #log_wait_start, #log_warn, #logger
Constructor Details
#initialize(max_size: 100, ttl: 300) ⇒ Cache
Returns a new instance of Cache.
14 15 16 17 18 19 20 |
# File 'lib/appom/element_cache.rb', line 14 def initialize(max_size: 100, ttl: 300) @cache = {} @access_times = {} @max_size = max_size @ttl = ttl # Time to live in seconds @stats = { hits: 0, misses: 0, evictions: 0, stores: 0, clears: 0, expirations: 0 } end |
Instance Attribute Details
#max_size ⇒ Object (readonly)
Returns the value of attribute max_size.
12 13 14 |
# File 'lib/appom/element_cache.rb', line 12 def max_size @max_size end |
#ttl ⇒ Object (readonly)
Returns the value of attribute ttl.
12 13 14 |
# File 'lib/appom/element_cache.rb', line 12 def ttl @ttl end |
Instance Method Details
#clear ⇒ Object
Clear all cached elements
113 114 115 116 117 118 |
# File 'lib/appom/element_cache.rb', line 113 def clear @cache.clear @access_times.clear @stats[:clears] += 1 log_info('Element cache cleared') end |
#generate_key(*args) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/appom/element_cache.rb', line 158 def generate_key(*args) # Handle both old and new calling patterns find_args = if args.length == 1 && args[0].is_a?(Array) # Old pattern: generate_key([strategy, value]) args[0] else # New pattern: generate_key(strategy, value) args end # Create consistent cache key from find arguments Digest::MD5.hexdigest(find_args.to_s) end |
#get(cache_key) ⇒ Object
Get element from cache by key
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/appom/element_cache.rb', line 31 def get(cache_key) unless @cache.key?(cache_key) @stats[:misses] += 1 return nil end element, = @cache[cache_key] # Check TTL if Time.now - > @ttl @cache.delete(cache_key) @access_times.delete(cache_key) @stats[:expirations] ||= 0 @stats[:expirations] += 1 @stats[:misses] += 1 return nil end # Check if element is still valid unless valid_element?(element) @cache.delete(cache_key) @access_times.delete(cache_key) @stats[:misses] += 1 return nil end # Update access time and refresh TTL current_time = Time.now @cache[cache_key] = [element, current_time] @access_times[cache_key] = current_time @stats[:hits] += 1 element end |
#get_or_find(*find_args) ⇒ Object
Get element from cache or find and cache it
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/appom/element_cache.rb', line 83 def get_or_find(*find_args) cache_key = generate_key(find_args) if (cached_element = get(cache_key)) log_debug("Cache HIT for #{find_args.join(', ')}") return cached_element end @stats[:misses] += 1 log_debug("Cache MISS for #{find_args.join(', ')}") # Find element and cache it element = yield if block_given? store_in_cache(cache_key, element) if element element end |
#hit?(cache_key) ⇒ Boolean
Check if key exists in cache
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/appom/element_cache.rb', line 66 def hit?(cache_key) return false unless @cache.key?(cache_key) element, = @cache[cache_key] # Check TTL without updating stats return false if Time.now - > @ttl valid_element?(element) end |
#invalidate(*find_args) ⇒ Object
Invalidate specific element
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/appom/element_cache.rb', line 101 def invalidate(*find_args) # rubocop:disable Naming/PredicateMethod cache_key = generate_key(find_args) if @cache.delete(cache_key) @access_times.delete(cache_key) log_debug("Invalidated cache for #{find_args.join(', ')}") true else false end end |
#reset ⇒ Object
Clear all cached elements and reset statistics
121 122 123 124 125 126 |
# File 'lib/appom/element_cache.rb', line 121 def reset @cache.clear @access_times.clear @stats = { hits: 0, misses: 0, evictions: 0, stores: 0, clears: 0, expirations: 0 } log_info('Element cache reset') end |
#size ⇒ Object
Get cache size
78 79 80 |
# File 'lib/appom/element_cache.rb', line 78 def size @cache.size end |
#statistics ⇒ Object
Get cache statistics
129 130 131 132 133 134 135 136 |
# File 'lib/appom/element_cache.rb', line 129 def statistics { size: @cache.size, max_size: @max_size, hit_rate: calculate_hit_rate, **@stats, } end |
#stats ⇒ Object
Alias for backward compatibility
139 140 141 |
# File 'lib/appom/element_cache.rb', line 139 def stats statistics end |
#store(strategy, value, element) ⇒ Object
Store element in cache with strategy and value
23 24 25 26 27 28 |
# File 'lib/appom/element_cache.rb', line 23 def store(strategy, value, element) cache_key = generate_key(strategy, value) store_in_cache(cache_key, element) @stats[:stores] += 1 cache_key end |
#valid_element?(element) ⇒ Boolean
Check if element is still valid (exists and is stale)
144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/appom/element_cache.rb', line 144 def valid_element?(element) return false unless element return true unless element.respond_to?(:displayed?) begin # Try to access a property to check if element is stale element.displayed? true rescue StandardError # Element is stale or invalid false end end |