Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes in views in database are ignored in production until Rails is restarted #18

Open
pbartel opened this issue Sep 9, 2015 · 13 comments

Comments

@pbartel
Copy link

pbartel commented Sep 9, 2015

It seems the view is cached when it is first read in production. Is this related to Rails or Panoramic? I would like to flush the cache when the view is updated.

@andreapavoni
Copy link
Owner

according to this spec, the cache is cleared when you update a view.

Try to run tests locally to see if this still applies.

On the Rails side, open your config/environments/production.rb and check for these values:

config.cache_classes = false # controls whether or not application classes and modules should be reloaded on each request
config.action_view.cache_template_loading = false # controls whether or not templates should be reloaded on each request

Refer to the official guide for more details.

Let me know how it evolves :-)

@nhodges
Copy link
Contributor

nhodges commented Feb 20, 2016

@apeacox do you plan to add support for centralized caching? I am using this gem in an application that is load balanced so it's not useful to use the Rails cache because the change must be effected across multiple environments.

To note, I did try just using redis as cache_store in application.rb but that didn't seem to work.

@andreapavoni
Copy link
Owner

@nhodges this looks something that needs some investigation. in theory, the mechanism used by panoramic is the same of the standard rails (except it reads from a db rather than from a filesystem). If you know a method to do centralized caching with plain rails views, perhaps we could find a solution for panoramic too.

PRs are welcome :-)

@savroff
Copy link

savroff commented Jul 25, 2016

We have a similar setup to your gem with liquid in our SAAS project. We drop templates cache only in case if someone changed templates.
This make perfect sense, but problem that we want to drop only specific views cache)) if we solve this problem, we share with u guys

@petercip
Copy link

petercip commented Nov 4, 2016

I had this problem as well, with mailer templates not being updated in Delayed Job after they were changed in the database. For Delayed Job, the code below fixes the issue. Replace __YOUR_VIEW_MODEL__ with the name of the model that stores your templates, and put this in config/initializers.

class DoNotCacheDatabaseViewTemplates < Delayed::Plugin
  callbacks do |lifecycle|
    lifecycle.before(:execute) do |job|
      __YOUR_VIEW_MODEL__.resolver.caching=false
    end
  end
end

Delayed::Worker.plugins << DoNotCacheDatabaseViewTemplates

If the issue occurs in because your environment runs multiple rails processes, you may try an initializer file containing __YOUR_VIEW_MODEL__.resolver.caching=false. That will stop all caching of Panoramic views within Rails' resolver.

@DanBrooker
Copy link

@petercip how does turning off the resolver caching impact performance?

@petercip
Copy link

@DanBrooker it has been negligible. If you're sending a massive volume of mail, it might be noticeable.

@vitobotta
Copy link

Hi @petercip, are you still happy with caching turned off? What kind of traffic does this handle now? Or have you found a way to expire only the cache of a template when it's updated? Thanks!

@Velora
Copy link

Velora commented Jun 5, 2020

As I understand it, the issue is that after_save { Panoramic::Resolver.instance.clear_cache } won't work on multi-instance/multi-server deployments. We use memcached as a cache store, but this doesn't seem to be used for templates.

__YOUR_VIEW_MODEL__.resolver.caching=false in an initializer doesn't seem to have any effect for me on Rails 5.2.

Does anyone have suggestions of how we could ensure that our memcached store is being used, or how we can use __YOUR_VIEW_MODEL__.resolver.caching=false to disable caching for this view model only?

config.action_view.cache_template_loading = false would disable all view template caching and solve this, but doing so would create a massive and unsustainable decrease in performance.

Hoping someone has found a solution to be able to use panoramic in a multi-instance deployment. Thanks!

@Velora
Copy link

Velora commented Jun 6, 2020

So far my best solution is to override the Actionview::Resolver cached method in panoramic so that the cache will never be called. This doesn't feel like an ideal solution so I am curious to hear how others have handled it, and if anyone was able to work towards a solution for centralized caching of view templates.

@asecondwill
Copy link

@Velora - can you share how you overrode the cache method? Have you found a better solution?

@Velora
Copy link

Velora commented Jul 24, 2020

@asecondwill sure. No, we have not found a better solution yet.

We have an initializer that looks something like this:

YourViewModel.class_eval do
  self.resolver.caching = false
end

Panoramic::Resolver.class_eval do
  private

  def initialize_template(record)
    source = record.body
    identifier = "#{record.class} - #{record.id} - #{record.path.inspect}"
    handler = ActionView::Template.registered_template_handler(record.handler)

    details = {
        :format => Mime[record.format].to_sym,
        :updated_at => Time.now, # this avoids template cache for tenants
        :virtual_path => virtual_path(record.path, record.partial)
    }
    ActionView::Template.new(source, identifier, handler, details)
  end
end

@Shaglock
Copy link

@Velora thank you for your solution, it helped me with the same problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants