summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2018-05-04 19:23:08 +0200
committerRémy Coutable <remy@rymai.me>2018-05-23 16:14:43 +0200
commit02f17a0988acfdc60d7e1f920e8f750cb81f09d0 (patch)
treee9ba4c4eae51eedf06c998fb3892bb599a347314 /app/models
parenta2dbca4a27b8f380652bf1165f89238895b0f5d8 (diff)
downloadgitlab-ce-02f17a0988acfdc60d7e1f920e8f750cb81f09d0.tar.gz
Introduce a new CacheableAttributes concern
Signed-off-by: Rémy Coutable <remy@rymai.me>
Diffstat (limited to 'app/models')
-rw-r--r--app/models/concerns/cacheable_attributes.rb54
1 files changed, 54 insertions, 0 deletions
diff --git a/app/models/concerns/cacheable_attributes.rb b/app/models/concerns/cacheable_attributes.rb
new file mode 100644
index 00000000000..b32459fdabf
--- /dev/null
+++ b/app/models/concerns/cacheable_attributes.rb
@@ -0,0 +1,54 @@
+module CacheableAttributes
+ extend ActiveSupport::Concern
+
+ included do
+ after_commit { self.class.expire }
+ end
+
+ class_methods do
+ # Can be overriden
+ def current_without_cache
+ last
+ end
+
+ def cache_key
+ "#{name}:#{Gitlab::VERSION}:#{Gitlab.migrations_hash}:json".freeze
+ end
+
+ def defaults
+ {}
+ end
+
+ def build_from_defaults(attributes = {})
+ new(defaults.merge(attributes))
+ end
+
+ def cached
+ json_attributes = Rails.cache.read(cache_key)
+ return nil unless json_attributes.present?
+
+ build_from_defaults(JSON.parse(json_attributes))
+ end
+
+ def current
+ cached_record = cached
+ return cached_record if cached_record.present?
+
+ current_without_cache.tap { |current_record| current_record&.cache! }
+ rescue
+ # Fall back to an uncached value if there are any problems (e.g. Redis down)
+ current_without_cache
+ end
+
+ def expire
+ Rails.cache.delete(cache_key)
+ rescue
+ # Gracefully handle when Redis is not available. For example,
+ # omnibus may fail here during gitlab:assets:compile.
+ end
+ end
+
+ def cache!
+ Rails.cache.write(self.class.cache_key, attributes.to_json)
+ end
+end