about summary refs log tree commit diff
path: root/app/lib/entity_cache.rb
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-04-27 01:38:10 +0200
committerGitHub <noreply@github.com>2018-04-27 01:38:10 +0200
commita872392cd958167d5d9dd3fef613415cc9068774 (patch)
treeb062e9d8c7e87c29c74fb5416f3f60f39a172301 /app/lib/entity_cache.rb
parent63553c6b5c927950a45c5acb5af32af0dacee8c9 (diff)
Add entity cache (#7271)
* Add entity cache

Use a caching layer for mentions and custom emojis that are
dynamically extracted from text.

Reduce duplicate text extractions

* Fix code style issue
Diffstat (limited to 'app/lib/entity_cache.rb')
-rw-r--r--app/lib/entity_cache.rb34
1 files changed, 34 insertions, 0 deletions
diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb
new file mode 100644
index 000000000..0c4edbfab
--- /dev/null
+++ b/app/lib/entity_cache.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'singleton'
+
+class EntityCache
+  include Singleton
+
+  MAX_EXPIRATION = 7.days.freeze
+
+  def mention(username, domain)
+    Rails.cache.fetch(to_key(:mention, username, domain), expires_in: MAX_EXPIRATION) { Account.select(:username, :domain, :url).find_remote(username, domain) }
+  end
+
+  def emoji(shortcodes, domain)
+    shortcodes   = [shortcodes] unless shortcodes.is_a?(Array)
+    cached       = Rails.cache.read_multi(*shortcodes.map { |shortcode| to_key(:emoji, shortcode, domain) })
+    uncached_ids = []
+
+    shortcodes.each do |shortcode|
+      uncached_ids << shortcode unless cached.key?(to_key(:emoji, shortcode, domain))
+    end
+
+    unless uncached_ids.empty?
+      uncached = CustomEmoji.where(shortcode: shortcodes, domain: domain, disabled: false).select(:shortcode, :id, :image_file_name, :visible_in_picker).map { |item| [item.shortcode, item] }.to_h
+      uncached.each_value { |item| Rails.cache.write(to_key(:emoji, item.shortcode, domain), item, expires_in: MAX_EXPIRATION) }
+    end
+
+    shortcodes.map { |shortcode| cached[to_key(:emoji, shortcode, domain)] || uncached[shortcode] }.compact
+  end
+
+  def to_key(type, *ids)
+    "#{type}:#{ids.compact.map(&:downcase).join(':')}"
+  end
+end