huacnlee / rails-settings-cached

Global settings for your Rails application.
Other
1.06k stars 202 forks source link

Cache doesn't clean for distributed system #182

Closed vitalinfo closed 4 years ago

vitalinfo commented 4 years ago

I have a few web-servers and a few sidekiq worksers and use Redis store as a primary cache. If update any setting from the one web-server application, it doesn't update on another instances, because of RequestStore local cache. Doesn't it make any sense to use RequestStore? Why just not use Rails.cache as a one source of thrust?

rhombl4 commented 3 years ago

@vitalinfo how did you solve your issue?

Piioo commented 3 years ago

Same problem here.

@huacnlee is it possible to change the caching place? Or to disable it ?

Monkey Patch

module RailsSettings
  class RequestCache
    class << self
      def reset
        Rails.cache.write('foo', nil)
      end

      def settings
        Rails.cache.read('foo')
      end

      def settings=(val)
        Rails.cache.write('foo', val)
      end
    end
  end
end
rhombl4 commented 3 years ago

My workaround is that RequestStore exist only inside a single web-request/job/task. So on every request Rails reads Rails.cache for values and stores it to global variable within request, what RequestStore is. This situation happened for me because I was trying to check if my var is updated on different instances with rails console, but for this case console-session it is the single "request". To ensure that everything is working as suggested, I add debug-loggers into the different places of code and run this on instances. That confirms variables are changed as expected. The only issue when it can fail - some kind of long request with many Setting-readings when all queries are served by RequestCache.

huacnlee commented 3 years ago

Hi, all

I just create a Issue https://github.com/huacnlee/rails-settings-cached/issues/219

I will try to fix this problem.

huacnlee commented 3 years ago

My workaround is that RequestStore exist only inside a single web-request/job/task. So on every request Rails reads Rails.cache for values and stores it to global variable within request, what RequestStore is. This situation happened for me because I was trying to check if my var is updated on different instances with rails console, but for this case console-session it is the single "request". To ensure that everything is working as suggested, I add debug-loggers into the different places of code and run this on instances. That confirms variables are changed as expected. The only issue when it can fail - some kind of long request with many Setting-readings when all queries are served by RequestCache.

RequestCache it avoid Redis I/O, when on page have multiple setting keys wants to read.

huacnlee commented 3 years ago

For now, you can call RailsSettings::RequestCache.reset directly to clean RequestCache

rhombl4 commented 3 years ago

@huacnlee what was the case to use that in real environment?

huacnlee commented 3 years ago

version 2.8.0 fixed this.

vitalinfo commented 3 years ago

@rhombl4 sorry for the later answer, I've resolved it with https://github.com/madebylotus/request_store-sidekiq but looks like it isn't actual anymore

huacnlee commented 3 years ago

@vitalinfo For now, you not need it.