Class: Idempo::RedisBackend::Store
- Inherits:
-
Struct
- Object
- Struct
- Idempo::RedisBackend::Store
- Defined in:
- lib/idempo/redis_backend.rb
Instance Attribute Summary collapse
-
#key ⇒ Object
Returns the value of attribute key.
-
#lock_redis_key ⇒ Object
Returns the value of attribute lock_redis_key.
-
#lock_token ⇒ Object
Returns the value of attribute lock_token.
-
#redis_pool ⇒ Object
Returns the value of attribute redis_pool.
Instance Method Summary collapse
Instance Attribute Details
#key ⇒ Object
Returns the value of attribute key
32 33 34 |
# File 'lib/idempo/redis_backend.rb', line 32 def key @key end |
#lock_redis_key ⇒ Object
Returns the value of attribute lock_redis_key
32 33 34 |
# File 'lib/idempo/redis_backend.rb', line 32 def lock_redis_key @lock_redis_key end |
#lock_token ⇒ Object
Returns the value of attribute lock_token
32 33 34 |
# File 'lib/idempo/redis_backend.rb', line 32 def lock_token @lock_token end |
#redis_pool ⇒ Object
Returns the value of attribute redis_pool
32 33 34 |
# File 'lib/idempo/redis_backend.rb', line 32 def redis_pool @redis_pool end |
Instance Method Details
#lookup ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/idempo/redis_backend.rb', line 33 def lookup response_redis_key = "idempo:response:#{key}" redis_pool.with do |r| bin_str = r.get(response_redis_key) bin_str&.force_encoding(Encoding::BINARY) end end |
#store(data:, ttl:) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/idempo/redis_backend.rb', line 41 def store(data:, ttl:) response_redis_key = "idempo:response:#{key}" ttl_millis = (ttl * 1000.0).round # We save our payload using a script, and we will _only_ save it if our lock is still held. # If our lock expires during the request - for example our app.call takes too long - # we might have lost it, and another request has already saved a payload on our behalf. At this point # we have no guarantee that our response was generated exclusively, or that the response that was generated # by our "competitor" is equal to ours, or that a "competing" request is not holding our lock and executing the # same workload as we just did. The only sensible thing to do when we encounter this is to actually _skip_ the write. keys = [lock_redis_key, response_redis_key] argv = [lock_token, data.force_encoding(Encoding::BINARY), ttl_millis] outcome_of_save = redis_pool.with do |r| Idempo::RedisBackend.eval_or_evalsha(r, SET_WITH_TTL_IF_LOCK_STILL_HELD_SCRIPT, keys: keys, argv: argv) end Measurometer.increment_counter("idempo.redis_lock_state_when_saving_response", 1, state: outcome_of_save) end |