reason for action_cache before_filter?

Hey

Here's the code for action_cache around_filters...

  def before(controller)     return unless @actions.include?(controller.action_name.intern)     action_cache_path = ActionCachePath.new(controller)     if cache = controller.read_fragment(action_cache_path.path)       controller.rendered_action_cache = true       set_content_type!(action_cache_path)       controller.send(:render_text, cache)       false     end   end

  def after(controller)     return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache     controller.write_fragment(ActionCachePath.path_for(controller), controller.response.body)   end

Why isn't the before_filter just the first line (checking to see if the current action need be cached), with the rest of its code in the after_filter? I'm trying to figure out what the consequences would be of:

  def before(controller)     return unless @actions.include?(controller.action_name.intern)   end

  def after(controller)     action_cache_path = ActionCachePath.new(controller)     if cache = controller.read_fragment(action_cache_path.path)       controller.rendered_action_cache = true       set_content_type!(action_cache_path)       controller.send(:render_text, cache)       false     end

    return if !@actions.include?(controller.action_name.intern) || controller.rendered_action_cache     controller.write_fragment(ActionCachePath.path_for(controller), controller.response.body)   end

Thanks in advance Gustav Paul gustav@rails.co.za

The whole point of the Action Cache is to avoid executing the action.

With your modifications, the action is always executed. The purpose of the before_filter is to send the cached result instead of executing the action - the 'false' line tells Rails to stop executing filters and not call the action method. If you remove the before_filter code, the action will always execute.

No, this didn't answer the first question. But it did answer the second, completely unrelated question about the Action Cache before_filter code.

For the first question: Rails doesn't do threading, and has a lock to keep multiple threads out of the Rails code (trust me, don't try and get around this)

To run long-running background tasks, check out Ezra's BackgroundRB system: Ruby on Rails Blog / What is Ruby on Rails for?, it may help you do what you want

Thanks Tom!

I've since figured this out after long hours of sweating over a plugin! :]

I asked because I wanted to start working on a plugin (patch?) that'd let you keep multiple versions of an action_cached page. I've since opted for an around_filter approach (which also circumvents the code in the action of course ;] ), and its working beautifully! At the moment the syntax looks as follows:

class WelcomeController < ApplicationController

  cache_filter :index, :faq do | cache |     if cache.session[:logged_in]       cache.as :logged_in     else       cache.as :logged_out     end   end

  def index   end

  def faq   end

end

Anyway, I've finished it earlier this evening and applied to have the plugin kept at rubyforge. I'll post to the list once its checked in.

Thanks again for the help man! When I started out I though action_caching would still execute the code in the action (now it seems so obvious that it shouldn't, but back then it wasn't :] ) but just serve the rendered tempalte from cache instead of doing all the ERb stuff etc...

This is the first time I've gone peeking into the rails source, which has given me a new found respect for all the contributors!

Anyway, thanks again,

Cheery-o Gustav Paul gustav@rails.co.za

Tom Fakes wrote:

Wow, I should have proof-read that last post ; /

Sorry about the spelling errors...they irk me as much as anyone.

Gustav Paul gustav@rails.co.za

My action_cache plugin already allows this type of behavior, in a different way.

I've used it in an app to cache for 'admin', 'logged in user' and 'not logged in user', and my site uses themes, so the theme name is also part of the cache key. It is configurable to allow any available setting to be used to influence the cache.

Check it my blog postings (http://blog.craz8.com/) for details, script\plugin install action_cache will get the latest code.

My plugin also fixes some bugs in Rails action_cache, and does stuff like return 304s for unchanged content. The latest version can also use the x-sendfile header in lighttpd and x-accel-redirect in nginx to further reduce overhead.

Hi Tom

I checked out your plugin and it is excellent! The bottom code is the part that let's you assign custom keys?

ActionController::Caching::Actions::ActionCacheFilter.fragment_key = Proc.new {|controller|

"AC:#{controller.request.host_with_port}:#{controller.params.sort.join(':').gsub(' ', '-')}" }

Obviously the developer can make the block more interesting as he's got access to the controller object etc. (but you wrote it, so you know :] )

The only thing I prefer about my plugin is the syntax, but perhaps I can integrate it with your plugin so mine acts as a simpler wrapper. From looking at your plugin, it seems like mine will already wrap yours with no modifications to either! I only modify ActionCachePath, and add a class method and class variable to ActionController...none of which look like they intrude upon your work. If you don't mind, I'll run both on the same project for a while and let you know how it goes.

Thanks for your great work dude! Its really excellent! In short, my plugin doesn't mod action_cache in any way that interferes with yours, so if your plugin is installed on the same project, I'm pretty sure mine will make full use of it, giving the best of both to the developer.

But like I said, I'll be trying them out in parallel and see if they can enjoy a symbiotic relationship.

I still haven't uploaded mine to rubyforge, but the moment I do I'll be sure to let you know(if you're interested in the least :] )

Cheery-o Gustav Paul gustav@rails.co.za

Tom Fakes wrote: