Rails 3.2:到期后立即预渲染(烘焙)新的页面缓存吗? [英] Rails 3.2: Pre-render (bake) a new page cache immediately after expiry?

查看:90
本文介绍了Rails 3.2:到期后立即预渲染(烘焙)新的页面缓存吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个将 caches_page 用于某些控制器/动作的应用程序。为了使缓存过期,我使用了清除程序。总而言之,这是一个标准的解决方案。

I have an application that uses caches_page for certain controllers/actions. To expire the cache, I use a sweeper. All in all, it's a standard solution.

但是,由于某些更改可能会导致服务器上出现一些请求高峰(因为发送了推送通知,并且可能触发客户端设备以获取新数据),我希望能够预呈现缓存,因此在请求进入之前就已经准备好了。我当然可以等待第一个请求自动写入缓存,但是在这种情况下,我知道,请求将会到来,可能会有很多,并且它们可能几乎是同时发生的。因此,我想准备好缓存。

However, because some changes may cause a bit of a rush of requests on the server (because push notifications are sent out and may trigger client devices to fetch new data), I'd like to be able to pre-render the cache, so it's ready before the requests roll in. I could just wait for the first request to automatically write the cache, of course, but in this case, I know that the requests will come, that there might be many, and that they may be near-simultaneous. So I'd like to have the cache ready.

为了增加一些复杂性,更新是通过普通网页完成的,并在标准的,大多为脚手架的控制器中进行处理,而我要缓存的页面是充当API的完全不同的控制器的JSON响应。

To add some complexity, the updates are done via a normal web page and handled in a standard, mostly scaffolded controller, while the "page" I want to cache is the JSON response for an entirely different controller that serves as an API.

那么,如何从清除程序(或从处理高速缓存过期更新的控制器)触发立即写入新页面高速缓存?

另一种放置方式可能是:如何从一个控制器向另一个控制器发出内部请求?

Another way to put it might be: How do I make an internal request from one controller to another?

编辑:最终做了类似下面的操作。它不是很优雅,但是很有效

Ended up doing something like what you see below. It's not terribly elegant, but it is effective

class ModelSweeper < ActionController::Caching::Sweeper
  observe Model

  def after_create(model)
    expire_pages_for(model)
  end

  def after_update(model)
    expire_pages_for(model)
  end

  def after_destroy(model)
    expire_pages_for(model)
  end

  protected

    def expire_pages_for(model)
      # expire index page
      expire_and_bake(models_url)

      # expire show page
      expire_and_bake(model_url(model))
    end

    def expire_and_bake(url)
      # extract the path from the URL
      path = url.sub(%r{\Ahttp://[^/]+}, "")

      # expire the cache
      expire_page(path)

      # request the url (writes a new cache)
      system "curl '#{url}' &> /dev/null &"
    end

end


推荐答案

温暖服务器的缓存可能不在应用程序逻辑范围之内。在使用包裹了curl命令并遍历网站中所有区域的rake任务之前,我已经实现了缓存预热系统。

Warming a server's cache may fall outside of the realm of your application logic. I have implemented a cache warming system before using a rake task that wrapped the curl command and looped through all the areas in the website.

# lib/tasks/curl.rake
desc "curl"
task :curl do
  paths.each do |path|  
  `curl #{path}`
  end
end

您可以通过从Rails项目根目录内部发出 rake curl来调用此任务。

You can call this task by issuing "rake curl" from inside your Rails project root.

或者,您可以从清扫程序内部调用此rake任务(包裹curl)。缓存过期后的方法。查看Railscast Ryan Bates在后台从Rails应用程序代码中调用rake任务时所做的事情: http://railscasts.com/episodes/127-rake-in-background

Alternately, you could invoke this rake task (which wraps curl) from inside your sweeper method after you expire the cache. Check out the Railscast Ryan Bates did on invoking rake tasks in the background from inside your Rails application code: http://railscasts.com/episodes/127-rake-in-background

此处有关curl的更多信息: http://curl.haxx.se/docs/manpage.html

More information on curl here: http://curl.haxx.se/docs/manpage.html

这篇关于Rails 3.2:到期后立即预渲染(烘焙)新的页面缓存吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆