Class: AtomicCache::AtomicCacheClient
- Inherits:
-
Object
- Object
- AtomicCache::AtomicCacheClient
- Defined in:
- lib/atomic_cache/atomic_cache_client.rb
Constant Summary collapse
- DEFAULT_MAX_RETRIES =
5- DEFAULT_GENERATE_TIME_MS =
30 seconds
30000- BACKOFF_DURATION_MS =
50
Instance Method Summary collapse
-
#fetch(keyspace, options = {}) { ... } ⇒ Object
Attempts to fetch the given keyspace, using an optional block to generate a new value when the cache is expired.
-
#initialize(storage: nil, timestamp_manager: nil, default_options: {}, logger: nil, metrics: nil) ⇒ AtomicCacheClient
constructor
A new instance of AtomicCacheClient.
Constructor Details
#initialize(storage: nil, timestamp_manager: nil, default_options: {}, logger: nil, metrics: nil) ⇒ AtomicCacheClient
Returns a new instance of AtomicCacheClient.
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/atomic_cache/atomic_cache_client.rb', line 18 def initialize(storage: nil, timestamp_manager: nil, default_options: {}, logger: nil, metrics: nil) = (DefaultConfig.instance.&.clone || {}).merge( || {}) = @logger = logger || DefaultConfig.instance.logger @metrics = metrics || DefaultConfig.instance.metrics @storage = storage || DefaultConfig.instance.cache_storage raise ArgumentError.new("`timestamp_manager` required but none given") unless .present? raise ArgumentError.new("`storage` required but none given") unless @storage.present? end |
Instance Method Details
#fetch(keyspace, options = {}) { ... } ⇒ Object
Attempts to fetch the given keyspace, using an optional block to generate a new value when the cache is expired
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/atomic_cache/atomic_cache_client.rb', line 37 def fetch(keyspace, ={}, &blk) key = .current_key(keyspace) = ["cache_keyspace:#{keyspace.root}"] # happy path: see if the value is there in the key we expect value = @storage.read(key, ) if key.present? if !value.nil? metrics(:increment, 'read.present', tags: ) log(:debug, "Read value from key: '#{key}'") return value end metrics(:increment, 'read.not-present', tags: ) log(:debug, "Cache key `#{key}` not present.") # try to generate a new value if another process already isn't if block_given? new_value = generate_and_store(keyspace, , , &blk) return new_value unless new_value.nil? end # attempt to fall back to the last known value value = last_known_value(keyspace, , ) return value if value.present? # wait for the other process if a last known value isn't there if key.present? return time('wait.run', tags: ) do wait_for_new_value(keyspace, , ) end end # At this point, there's no key, value, last known key, or last known value. # A block wasn't given or couldn't create a non-nil value making it # impossible to do anything else, so bail if !key.present? metrics(:increment, 'no-key.give-up') log(:warn, "Giving up fetching cache keyspace for root `#{keyspace.root}`. No key could be generated.") end nil end |