Class: ResilientReads::QueryCache
- Inherits:
-
Object
- Object
- ResilientReads::QueryCache
- Defined in:
- lib/resilient_reads/query_cache.rb
Overview
Caches SQL pattern-matching results (read vs write classification) so the regex does not need to run on every identical query string.
Mirrors the caching concept from active_record_proxy_adapters but is simpler — we only cache the boolean result of write_query? and skip_replica_routing? keyed by the SQL string.
Thread-safe via a Mutex around the internal Hash. Uses an LRU eviction strategy when the cache exceeds max_size.
Constant Summary collapse
- DEFAULT_MAX_SIZE =
10_000
Instance Attribute Summary collapse
-
#key_prefix ⇒ Object
readonly
Returns the value of attribute key_prefix.
-
#max_size ⇒ Object
readonly
Returns the value of attribute max_size.
Instance Method Summary collapse
- #clear! ⇒ Object
-
#fetch(sql) ⇒ Object
Fetch a cached value or compute it from the block.
-
#initialize(max_size: DEFAULT_MAX_SIZE, key_prefix: "rr_") ⇒ QueryCache
constructor
A new instance of QueryCache.
- #size ⇒ Object
- #stats ⇒ Object
Constructor Details
#initialize(max_size: DEFAULT_MAX_SIZE, key_prefix: "rr_") ⇒ QueryCache
Returns a new instance of QueryCache.
18 19 20 21 22 23 24 25 |
# File 'lib/resilient_reads/query_cache.rb', line 18 def initialize(max_size: DEFAULT_MAX_SIZE, key_prefix: "rr_") @max_size = max_size @key_prefix = key_prefix @store = {} @mutex = Mutex.new @hits = 0 @misses = 0 end |
Instance Attribute Details
#key_prefix ⇒ Object (readonly)
Returns the value of attribute key_prefix.
16 17 18 |
# File 'lib/resilient_reads/query_cache.rb', line 16 def key_prefix @key_prefix end |
#max_size ⇒ Object (readonly)
Returns the value of attribute max_size.
16 17 18 |
# File 'lib/resilient_reads/query_cache.rb', line 16 def max_size @max_size end |
Instance Method Details
#clear! ⇒ Object
64 65 66 67 68 69 70 |
# File 'lib/resilient_reads/query_cache.rb', line 64 def clear! @mutex.synchronize do @store.clear @hits = 0 @misses = 0 end end |
#fetch(sql) ⇒ Object
Fetch a cached value or compute it from the block. The block receives the SQL and should return the value to cache.
cache.fetch(sql) { |s| ResilientReads.write_query?(s) }
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/resilient_reads/query_cache.rb', line 32 def fetch(sql) key = cache_key(sql) @mutex.synchronize do if @store.key?(key) @hits += 1 # Move to end (most recently used) value = @store.delete(key) @store[key] = value return value end end value = yield(sql) @mutex.synchronize do @misses += 1 @store[key] = value evict! if @store.size > @max_size end value end |
#size ⇒ Object
56 57 58 |
# File 'lib/resilient_reads/query_cache.rb', line 56 def size @mutex.synchronize { @store.size } end |
#stats ⇒ Object
60 61 62 |
# File 'lib/resilient_reads/query_cache.rb', line 60 def stats @mutex.synchronize { { hits: @hits, misses: @misses, size: @store.size } } end |