From a872392cd958167d5d9dd3fef613415cc9068774 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 27 Apr 2018 01:38:10 +0200 Subject: 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 --- app/lib/entity_cache.rb | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 app/lib/entity_cache.rb (limited to 'app/lib/entity_cache.rb') 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 -- cgit From 295e3ef02bb3fcdd4d8992ad6105c0ada2b3db0c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 30 Apr 2018 09:12:55 +0200 Subject: Fix missing domain attribute in EntityCache for emoji (#7290) --- app/lib/entity_cache.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/lib/entity_cache.rb') diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb index 0c4edbfab..03bfb7cf0 100644 --- a/app/lib/entity_cache.rb +++ b/app/lib/entity_cache.rb @@ -21,7 +21,7 @@ class EntityCache 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 = CustomEmoji.where(shortcode: shortcodes, domain: domain, disabled: false).select(:shortcode, :id, :domain, :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 -- cgit From 705f1d7bf15b7dc46256ab4a3bfff4075c79a8e7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 30 Apr 2018 22:49:33 +0200 Subject: Fix missing updated_at attribute on emoji EntityCache (#7297) Just don't try to save space by only selecting few attributes. If anyone is wondering, this is needed because the emoji entity cache is not really only used for entities, it's accessed again to generate Emoji tags in ActivityPub/OStatus, so a lot more properties are used than what is needed in HTML alone... --- app/lib/entity_cache.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/lib/entity_cache.rb') diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb index 03bfb7cf0..2aa37389c 100644 --- a/app/lib/entity_cache.rb +++ b/app/lib/entity_cache.rb @@ -21,7 +21,7 @@ class EntityCache end unless uncached_ids.empty? - uncached = CustomEmoji.where(shortcode: shortcodes, domain: domain, disabled: false).select(:shortcode, :id, :domain, :image_file_name, :visible_in_picker).map { |item| [item.shortcode, item] }.to_h + uncached = CustomEmoji.where(shortcode: shortcodes, domain: domain, disabled: false).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 -- cgit