diff options
author | Reuben Pereira <rpereira@gitlab.com> | 2019-04-04 17:27:29 +0000 |
---|---|---|
committer | Michael Kozono <mkozono@gmail.com> | 2019-04-04 17:27:29 +0000 |
commit | 5caced3650bf51bd1035347b9823367dd9095e02 (patch) | |
tree | e0a1467406fdc7a530d66a0e4fdc07546466238c /app | |
parent | a2d044bf97ec350019b2daebd962ab4901070818 (diff) | |
download | gitlab-ce-5caced3650bf51bd1035347b9823367dd9095e02.tar.gz |
Allow reactive caching to be used in services
Add support for defining a reactive_cache_worker_finder function
that will be used by the reactive_caching_worker to generate/initialize
the calling object. This allows reactive caching to work with Services
where the object cannot be obtained from DB but a new object can be
initialized.
Diffstat (limited to 'app')
-rw-r--r-- | app/models/concerns/reactive_caching.rb | 39 | ||||
-rw-r--r-- | app/workers/reactive_caching_worker.rb | 7 |
2 files changed, 43 insertions, 3 deletions
diff --git a/app/models/concerns/reactive_caching.rb b/app/models/concerns/reactive_caching.rb index 1ab3b3ddc46..1e09cd89550 100644 --- a/app/models/concerns/reactive_caching.rb +++ b/app/models/concerns/reactive_caching.rb @@ -29,6 +29,40 @@ # However, it will enqueue a background worker to call `#calculate_reactive_cache` # and set an initial cache lifetime of ten minutes. # +# The background worker needs to find or generate the object on which +# `with_reactive_cache` was called. +# The default behaviour can be overridden by defining a custom +# `reactive_cache_worker_finder`. +# Otherwise the background worker will use the class name and primary key to get +# the object using the ActiveRecord find_by method. +# +# class Bar +# include ReactiveCaching +# +# self.reactive_cache_key = ->() { ["bar", "thing"] } +# self.reactive_cache_worker_finder = ->(_id, *args) { from_cache(*args) } +# +# def self.from_cache(var1, var2) +# # This method will be called by the background worker with "bar1" and +# # "bar2" as arguments. +# new(var1, var2) +# end +# +# def initialize(var1, var2) +# # ... +# end +# +# def calculate_reactive_cache +# # Expensive operation here. The return value of this method is cached +# end +# +# def result +# with_reactive_cache("bar1", "bar2") do |data| +# # ... +# end +# end +# end +# # Each time the background job completes, it stores the return value of # `#calculate_reactive_cache`. It is also re-enqueued to run again after # `reactive_cache_refresh_interval`, so keeping the stored value up to date. @@ -52,6 +86,7 @@ module ReactiveCaching class_attribute :reactive_cache_key class_attribute :reactive_cache_lifetime class_attribute :reactive_cache_refresh_interval + class_attribute :reactive_cache_worker_finder # defaults self.reactive_cache_lease_timeout = 2.minutes @@ -59,6 +94,10 @@ module ReactiveCaching self.reactive_cache_refresh_interval = 1.minute self.reactive_cache_lifetime = 10.minutes + self.reactive_cache_worker_finder = ->(id, *_args) do + find_by(primary_key => id) + end + def calculate_reactive_cache(*args) raise NotImplementedError end diff --git a/app/workers/reactive_caching_worker.rb b/app/workers/reactive_caching_worker.rb index 9ec8bcca4f3..b30864db802 100644 --- a/app/workers/reactive_caching_worker.rb +++ b/app/workers/reactive_caching_worker.rb @@ -3,7 +3,6 @@ class ReactiveCachingWorker include ApplicationWorker - # rubocop: disable CodeReuse/ActiveRecord def perform(class_name, id, *args) klass = begin class_name.constantize @@ -12,7 +11,9 @@ class ReactiveCachingWorker end return unless klass - klass.find_by(klass.primary_key => id).try(:exclusively_update_reactive_cache!, *args) + klass + .reactive_cache_worker_finder + .call(id, *args) + .try(:exclusively_update_reactive_cache!, *args) end - # rubocop: enable CodeReuse/ActiveRecord end |