Class: SidekiqSmartCache::Promise
- Inherits:
-
Object
- Object
- SidekiqSmartCache::Promise
- Defined in:
- lib/sidekiq_smart_cache/promise.rb
Instance Attribute Summary collapse
-
#args ⇒ Object
Returns the value of attribute args.
-
#expires_in ⇒ Object
Returns the value of attribute expires_in.
-
#job_interlock_timeout ⇒ Object
Returns the value of attribute job_interlock_timeout.
-
#klass ⇒ Object
Returns the value of attribute klass.
-
#method ⇒ Object
Returns the value of attribute method.
-
#object_param ⇒ Object
Returns the value of attribute object_param.
-
#timed_out ⇒ Object
Returns the value of attribute timed_out.
Instance Method Summary collapse
- #cache_tag ⇒ Object
- #enqueue_job! ⇒ Object
- #execute_and_wait(timeout, raise_on_timeout: false, stale_on_timeout: false) ⇒ Object (also: #fetch)
- #execute_and_wait!(timeout, stale_on_timeout: false) ⇒ Object (also: #fetch!)
- #existing_value(allow_stale: false) ⇒ Object
-
#initialize(klass: nil, object: nil, object_param: nil, method:, args: nil, cache_tag: nil, expires_in: 1.hour, job_interlock_timeout: nil) ⇒ Promise
constructor
A new instance of Promise.
- #interlock ⇒ Object
- #perform_now ⇒ Object
- #ready_within?(timeout) ⇒ Boolean
- #result ⇒ Object
- #stale_value_available? ⇒ Boolean
- #start ⇒ Object
- #timed_out? ⇒ Boolean
Constructor Details
#initialize(klass: nil, object: nil, object_param: nil, method:, args: nil, cache_tag: nil, expires_in: 1.hour, job_interlock_timeout: nil) ⇒ Promise
Returns a new instance of Promise.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 10 def initialize(klass: nil, object: nil, object_param: nil, method:, args: nil, cache_tag: nil, expires_in: 1.hour, job_interlock_timeout: nil) if object @klass = object.class.to_s @object_param = object.to_param elsif klass @klass = klass.to_s @object_param = object_param else raise "Must provide either klass or object" end raise "Must provide method" unless method @method = method.to_s @expires_in = expires_in.to_i @job_interlock_timeout = job_interlock_timeout || @expires_in @args = args @cache_tag = cache_tag end |
Instance Attribute Details
#args ⇒ Object
Returns the value of attribute args.
3 4 5 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 3 def args @args end |
#expires_in ⇒ Object
Returns the value of attribute expires_in.
3 4 5 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 3 def expires_in @expires_in end |
#job_interlock_timeout ⇒ Object
Returns the value of attribute job_interlock_timeout.
3 4 5 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 3 def job_interlock_timeout @job_interlock_timeout end |
#klass ⇒ Object
Returns the value of attribute klass.
3 4 5 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 3 def klass @klass end |
#method ⇒ Object
Returns the value of attribute method.
3 4 5 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 3 def method @method end |
#object_param ⇒ Object
Returns the value of attribute object_param.
3 4 5 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 3 def object_param @object_param end |
#timed_out ⇒ Object
Returns the value of attribute timed_out.
4 5 6 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 4 def timed_out @timed_out end |
Instance Method Details
#cache_tag ⇒ Object
29 30 31 32 33 34 35 36 37 38 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 29 def cache_tag @cache_tag ||= begin [ klass, (object_param || '.'), method, (Digest::MD5.hexdigest(args.compact.to_json) if args.present?) ].compact * '/' end end |
#enqueue_job! ⇒ Object
48 49 50 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 48 def enqueue_job! Worker.perform_async(klass, object_param, method, args, cache_tag, expires_in) end |
#execute_and_wait(timeout, raise_on_timeout: false, stale_on_timeout: false) ⇒ Object Also known as: fetch
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 90 def execute_and_wait(timeout, raise_on_timeout: false, stale_on_timeout: false) previous_result = result if previous_result&.fresh? # found a previously fresh message @timed_out = false return previous_result.value else start # either a job was already running or we started one, now wait for an answer if redis.(cache_tag, timeout.to_i) # ready now, fetch it log('promise calculator job finished') @timed_out = false result.value elsif previous_result && stale_on_timeout log('promise timed out awaiting calculator job, serving stale') previous_result.value else log('promise timed out awaiting calculator job') @timed_out = true raise TimeoutError if raise_on_timeout end end end |
#execute_and_wait!(timeout, stale_on_timeout: false) ⇒ Object Also known as: fetch!
52 53 54 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 52 def execute_and_wait!(timeout, stale_on_timeout: false) execute_and_wait(timeout, raise_on_timeout: true, stale_on_timeout: stale_on_timeout) end |
#existing_value(allow_stale: false) ⇒ Object
64 65 66 67 68 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 64 def existing_value(allow_stale: false) if((existing = result) && (allow_stale || existing.fresh?)) existing.value end end |
#interlock ⇒ Object
40 41 42 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 40 def interlock @_interlock ||= Interlock.new(cache_tag, job_interlock_timeout) end |
#perform_now ⇒ Object
44 45 46 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 44 def perform_now Worker.new.perform(klass, object_param, method, args, cache_tag, expires_in) end |
#ready_within?(timeout) ⇒ Boolean
70 71 72 73 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 70 def ready_within?(timeout) execute_and_wait(timeout) !timed_out end |
#result ⇒ Object
56 57 58 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 56 def result Result.load_from(cache_tag) end |
#stale_value_available? ⇒ Boolean
60 61 62 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 60 def stale_value_available? !!result&.stale? end |
#start ⇒ Object
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 79 def start # Start a job if no other client has if interlock.lock_job? log('promise enqueuing calculator job') enqueue_job! else log('promise calculator job already working') end self # for chaining end |
#timed_out? ⇒ Boolean
75 76 77 |
# File 'lib/sidekiq_smart_cache/promise.rb', line 75 def timed_out? !!timed_out end |