summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrpereira2 <rpereira@gitlab.com>2019-04-02 11:11:34 +0530
committerPeter Leitzen <pleitzen@gitlab.com>2019-04-02 13:52:04 +0200
commitc91830d14a9141c39c80f91efd6322973211bb1f (patch)
treeb12387091947e63897a640549d21de32a4fa8c2f
parent9763c9cc0e3c12842ae214b314e2873b483f9583 (diff)
downloadgitlab-ce-c91830d14a9141c39c80f91efd6322973211bb1f.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.
-rw-r--r--app/models/concerns/reactive_caching.rb39
-rw-r--r--app/workers/reactive_caching_worker.rb7
-rw-r--r--changelogs/unreleased/58375-reactive-caching-changes.yml5
3 files changed, 48 insertions, 3 deletions
diff --git a/app/models/concerns/reactive_caching.rb b/app/models/concerns/reactive_caching.rb
index 1ab3b3ddc46..173f2379a72 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 overriden 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
diff --git a/changelogs/unreleased/58375-reactive-caching-changes.yml b/changelogs/unreleased/58375-reactive-caching-changes.yml
new file mode 100644
index 00000000000..cf73736b8ef
--- /dev/null
+++ b/changelogs/unreleased/58375-reactive-caching-changes.yml
@@ -0,0 +1,5 @@
+---
+title: Allow reactive caching to be used in services
+merge_request: 26839
+author:
+type: added