Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
03e9ea97
Commit
03e9ea97
authored
Apr 04, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
003d0641
465f82e3
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
92 additions
and
3 deletions
+92
-3
app/models/concerns/reactive_caching.rb
app/models/concerns/reactive_caching.rb
+39
-0
app/workers/reactive_caching_worker.rb
app/workers/reactive_caching_worker.rb
+4
-3
changelogs/unreleased/58375-reactive-caching-changes.yml
changelogs/unreleased/58375-reactive-caching-changes.yml
+5
-0
spec/models/concerns/reactive_caching_spec.rb
spec/models/concerns/reactive_caching_spec.rb
+44
-0
No files found.
app/models/concerns/reactive_caching.rb
View file @
03e9ea97
...
@@ -29,6 +29,40 @@
...
@@ -29,6 +29,40 @@
# However, it will enqueue a background worker to call `#calculate_reactive_cache`
# However, it will enqueue a background worker to call `#calculate_reactive_cache`
# and set an initial cache lifetime of ten minutes.
# 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
# Each time the background job completes, it stores the return value of
# `#calculate_reactive_cache`. It is also re-enqueued to run again after
# `#calculate_reactive_cache`. It is also re-enqueued to run again after
# `reactive_cache_refresh_interval`, so keeping the stored value up to date.
# `reactive_cache_refresh_interval`, so keeping the stored value up to date.
...
@@ -52,6 +86,7 @@ module ReactiveCaching
...
@@ -52,6 +86,7 @@ module ReactiveCaching
class_attribute
:reactive_cache_key
class_attribute
:reactive_cache_key
class_attribute
:reactive_cache_lifetime
class_attribute
:reactive_cache_lifetime
class_attribute
:reactive_cache_refresh_interval
class_attribute
:reactive_cache_refresh_interval
class_attribute
:reactive_cache_worker_finder
# defaults
# defaults
self
.
reactive_cache_lease_timeout
=
2
.
minutes
self
.
reactive_cache_lease_timeout
=
2
.
minutes
...
@@ -59,6 +94,10 @@ module ReactiveCaching
...
@@ -59,6 +94,10 @@ module ReactiveCaching
self
.
reactive_cache_refresh_interval
=
1
.
minute
self
.
reactive_cache_refresh_interval
=
1
.
minute
self
.
reactive_cache_lifetime
=
10
.
minutes
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
)
def
calculate_reactive_cache
(
*
args
)
raise
NotImplementedError
raise
NotImplementedError
end
end
...
...
app/workers/reactive_caching_worker.rb
View file @
03e9ea97
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
class
ReactiveCachingWorker
class
ReactiveCachingWorker
include
ApplicationWorker
include
ApplicationWorker
# rubocop: disable CodeReuse/ActiveRecord
def
perform
(
class_name
,
id
,
*
args
)
def
perform
(
class_name
,
id
,
*
args
)
klass
=
begin
klass
=
begin
class_name
.
constantize
class_name
.
constantize
...
@@ -12,7 +11,9 @@ class ReactiveCachingWorker
...
@@ -12,7 +11,9 @@ class ReactiveCachingWorker
end
end
return
unless
klass
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
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
changelogs/unreleased/58375-reactive-caching-changes.yml
0 → 100644
View file @
03e9ea97
---
title
:
Allow reactive caching to be used in services
merge_request
:
26839
author
:
type
:
added
spec/models/concerns/reactive_caching_spec.rb
View file @
03e9ea97
...
@@ -16,6 +16,10 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
...
@@ -16,6 +16,10 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
attr_reader
:id
attr_reader
:id
def
self
.
primary_key
:id
end
def
initialize
(
id
,
&
blk
)
def
initialize
(
id
,
&
blk
)
@id
=
id
@id
=
id
@calculator
=
blk
@calculator
=
blk
...
@@ -106,6 +110,46 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
...
@@ -106,6 +110,46 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
end
end
end
end
describe
'.reactive_cache_worker_finder'
do
context
'with default reactive_cache_worker_finder'
do
let
(
:args
)
{
%w(other args)
}
before
do
allow
(
instance
.
class
).
to
receive
(
:find_by
).
with
(
id:
instance
.
id
)
.
and_return
(
instance
)
end
it
'calls the activerecord find_by method'
do
result
=
instance
.
class
.
reactive_cache_worker_finder
.
call
(
instance
.
id
,
*
args
)
expect
(
result
).
to
eq
(
instance
)
expect
(
instance
.
class
).
to
have_received
(
:find_by
).
with
(
id:
instance
.
id
)
end
end
context
'with custom reactive_cache_worker_finder'
do
let
(
:args
)
{
%w(arg1 arg2)
}
let
(
:instance
)
{
CustomFinderCacheTest
.
new
(
666
,
&
calculation
)
}
class
CustomFinderCacheTest
<
CacheTest
self
.
reactive_cache_worker_finder
=
->
(
_id
,
*
args
)
{
from_cache
(
*
args
)
}
def
self
.
from_cache
(
*
args
);
end
end
before
do
allow
(
instance
.
class
).
to
receive
(
:from_cache
).
with
(
*
args
).
and_return
(
instance
)
end
it
'overrides the default reactive_cache_worker_finder'
do
result
=
instance
.
class
.
reactive_cache_worker_finder
.
call
(
instance
.
id
,
*
args
)
expect
(
result
).
to
eq
(
instance
)
expect
(
instance
.
class
).
to
have_received
(
:from_cache
).
with
(
*
args
)
end
end
end
describe
'#clear_reactive_cache!'
do
describe
'#clear_reactive_cache!'
do
before
do
before
do
stub_reactive_cache
(
instance
,
4
)
stub_reactive_cache
(
instance
,
4
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment