From c4a0f0c2a4f8a2fef484f65420527109ead15f83 Mon Sep 17 00:00:00 2001 From: viralpraxis Date: Fri, 13 Oct 2023 21:24:31 +0300 Subject: [PATCH 1/4] Implement configurable storage backend --- lib/rails-settings-cached.rb | 1 + lib/rails-settings/base.rb | 4 ++-- lib/rails-settings/configuration.rb | 33 +++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 lib/rails-settings/configuration.rb diff --git a/lib/rails-settings-cached.rb b/lib/rails-settings-cached.rb index 37da54e..db76a3a 100644 --- a/lib/rails-settings-cached.rb +++ b/lib/rails-settings-cached.rb @@ -10,6 +10,7 @@ require_relative "rails-settings/fields/string" require_relative "rails-settings/base" +require_relative "rails-settings/configuration" require_relative "rails-settings/request_cache" require_relative "rails-settings/middleware" require_relative "rails-settings/railtie" diff --git a/lib/rails-settings/base.rb b/lib/rails-settings/base.rb index 98ee617..c44da98 100644 --- a/lib/rails-settings/base.rb +++ b/lib/rails-settings/base.rb @@ -33,7 +33,7 @@ def clear_cache class << self def clear_cache RequestCache.reset - Rails.cache.delete(cache_key) + RailsSettings.configuration.storage.delete(cache_key) end def field(key, **opts) @@ -127,7 +127,7 @@ def rails_initialized? end def _all_settings - RequestCache.all_settings ||= Rails.cache.fetch(cache_key, expires_in: 1.week) do + RequestCache.all_settings ||= RailsSettings.configuration.storage.fetch(cache_key, expires_in: 1.week) do vars = unscoped.select("var, value") result = {} vars.each { |record| result[record.var] = record.value } diff --git a/lib/rails-settings/configuration.rb b/lib/rails-settings/configuration.rb new file mode 100644 index 0000000..7e10bf0 --- /dev/null +++ b/lib/rails-settings/configuration.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module RailsSettings + InvalidConfigurationError = Class.new(StandardError) + + class Configuration + attr_reader :storage + + def initialize + @storage = Rails.cache + end + + def storage=(value) + unless value.is_a?(ActiveSupport::Cache::Store) + raise InvalidConfigurationError, <<~TXT + Option `storage` must be an instance of `ActiveSupport::Cache::Store` class. + TXT + end + + @storage = value + end + end + + class << self + def configuration + @configuration ||= Configuration.new + end + + def configure + yield configuration + end + end +end From 540cfadbc05912c061f0c37983bcee857a773dc4 Mon Sep 17 00:00:00 2001 From: viralpraxis Date: Mon, 16 Oct 2023 09:17:08 +0300 Subject: [PATCH 2/4] Refactor `Configuration` class and its usage --- lib/rails-settings/base.rb | 8 ++++++-- lib/rails-settings/configuration.rb | 32 ++++++++++------------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/lib/rails-settings/base.rb b/lib/rails-settings/base.rb index c44da98..9fb81bc 100644 --- a/lib/rails-settings/base.rb +++ b/lib/rails-settings/base.rb @@ -33,7 +33,7 @@ def clear_cache class << self def clear_cache RequestCache.reset - RailsSettings.configuration.storage.delete(cache_key) + cache_storage.delete(cache_key) end def field(key, **opts) @@ -127,13 +127,17 @@ def rails_initialized? end def _all_settings - RequestCache.all_settings ||= RailsSettings.configuration.storage.fetch(cache_key, expires_in: 1.week) do + RequestCache.all_settings ||= cache_storage.fetch(cache_key, expires_in: 1.week) do vars = unscoped.select("var, value") result = {} vars.each { |record| result[record.var] = record.value } result.with_indifferent_access end end + + def cache_storage + RailsSettings.config.cache_storage + end end end end diff --git a/lib/rails-settings/configuration.rb b/lib/rails-settings/configuration.rb index 7e10bf0..10adfb0 100644 --- a/lib/rails-settings/configuration.rb +++ b/lib/rails-settings/configuration.rb @@ -1,33 +1,23 @@ # frozen_string_literal: true module RailsSettings - InvalidConfigurationError = Class.new(StandardError) - class Configuration - attr_reader :storage - - def initialize - @storage = Rails.cache - end - - def storage=(value) - unless value.is_a?(ActiveSupport::Cache::Store) - raise InvalidConfigurationError, <<~TXT - Option `storage` must be an instance of `ActiveSupport::Cache::Store` class. - TXT - end - - @storage = value - end + # Caching storage backend. + # Default: `Rails.cache` + attr_accessor :cache_storage end class << self - def configuration - @configuration ||= Configuration.new + def config + return @config if defined?(@config) + + @config = Configuration.new + @config.cache_storage = Rails.cache + @config end - def configure - yield configuration + def configure(&block) + config.instance_exec(&block) end end end From ebf5e5faf508ab35fe452a78d2e40b13fab8d70c Mon Sep 17 00:00:00 2001 From: viralpraxis Date: Mon, 16 Oct 2023 09:17:17 +0300 Subject: [PATCH 3/4] Update tests --- test/base_test.rb | 21 +++++++++++++++ test/configuration_test.rb | 13 +++++++++ .../lib/active_support/cache/dummy_store.rb | 27 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 test/configuration_test.rb create mode 100644 test/dummy/lib/active_support/cache/dummy_store.rb diff --git a/test/base_test.rb b/test/base_test.rb index c9d34b1..60f28a1 100644 --- a/test/base_test.rb +++ b/test/base_test.rb @@ -424,4 +424,25 @@ class NewSetting < RailsSettings::Base assert_equal %(SELECT "settings".* FROM "settings" WHERE (var like 'readonly_%')), Setting.by_prefix("readonly_").to_sql assert_equal "foo", Setting.by_prefix("readonly_").foo end + + class CustomCacheStorageTest < ActiveSupport::TestCase + setup do + RailsSettings.configure do + self.cache_storage = ActiveSupport::Cache.lookup_store(:dummy_store) + end + end + + teardown do + RailsSettings.configure do + self.cache_storage = Rails.cache + end + end + + test "uses expected cached storage" do + Setting.user_limits = 42 + + assert_equal Setting.user_limits, 42 + assert RailsSettings.config.cache_storage.data.keys.include?("rails-settings-cached/v2") + end + end end diff --git a/test/configuration_test.rb b/test/configuration_test.rb new file mode 100644 index 0000000..38ab452 --- /dev/null +++ b/test/configuration_test.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require "test_helper" + +class ConfigurationTest < ActiveSupport::TestCase + test "configuration" do + RailsSettings.configure do + self.cache_storage = ActiveSupport::Cache.lookup_store(:dummy_store) + end + + assert RailsSettings.config.cache_storage.instance_of? ActiveSupport::Cache::DummyStore + end +end diff --git a/test/dummy/lib/active_support/cache/dummy_store.rb b/test/dummy/lib/active_support/cache/dummy_store.rb new file mode 100644 index 0000000..7bd1217 --- /dev/null +++ b/test/dummy/lib/active_support/cache/dummy_store.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module ActiveSupport + module Cache + class DummyStore < Store + attr_reader :data + + def initialize(options = {}) + super(options) + + @data = {} + end + + def read_entry(key, _options) + data[key] + end + + def write_entry(key, value, _options) + data[key] = value + end + + def delete_entry(key, _options) + data.delete(key) + end + end + end +end From 694f3ad14fe0ace0b3548fa0cba64b86e6ec4bc7 Mon Sep 17 00:00:00 2001 From: viralpraxis Date: Mon, 16 Oct 2023 11:14:44 +0300 Subject: [PATCH 4/4] Fix flake test --- test/base_test.rb | 4 +++- test/dummy/lib/active_support/cache/dummy_store.rb | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/base_test.rb b/test/base_test.rb index 60f28a1..fff8fb0 100644 --- a/test/base_test.rb +++ b/test/base_test.rb @@ -442,7 +442,9 @@ class CustomCacheStorageTest < ActiveSupport::TestCase Setting.user_limits = 42 assert_equal Setting.user_limits, 42 - assert RailsSettings.config.cache_storage.data.keys.include?("rails-settings-cached/v2") + assert RailsSettings.config.cache_storage.data.keys.any? do |key| + key.start_with?("rails-settings-cached") + end end end end diff --git a/test/dummy/lib/active_support/cache/dummy_store.rb b/test/dummy/lib/active_support/cache/dummy_store.rb index 7bd1217..d4b3e1e 100644 --- a/test/dummy/lib/active_support/cache/dummy_store.rb +++ b/test/dummy/lib/active_support/cache/dummy_store.rb @@ -11,15 +11,15 @@ def initialize(options = {}) @data = {} end - def read_entry(key, _options) + def read_entry(key, **options) data[key] end - def write_entry(key, value, _options) + def write_entry(key, value, **options) data[key] = value end - def delete_entry(key, _options) + def delete_entry(key, **options) data.delete(key) end end