Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #8226 (closed defect: fixed)

Opened 2 years ago

Last modified 2 years ago

[PPATCH] big filter speedup

Reported by: skaes Assigned to: rick
Priority: normal Milestone: 1.2 regressions
Component: ActionPack Version: 1.2.3
Severity: major Keywords:
Cc:

Description

This patch replaces the current block/continuation filter chain handling by an implementation based on a simple loop. It is much faster than the old implementation.

Attachments

filter_speedup.patch (18.4 kB) - added by skaes on 04/30/07 18:40:42.
filter_speedup_fixed.patch (18.7 kB) - added by skaes on 04/30/07 19:31:54.
filter_speedup_fixed2.patch (18.7 kB) - added by skaes on 04/30/07 19:38:38.
deleted a superflous assignment
filter_speedup_trunk.patch (18.6 kB) - added by skaes on 04/30/07 20:02:45.
trunk version of the patch
filter_speedup_filter_chain_ordering_trunk.patch (4.1 kB) - added by skaes on 05/05/07 06:43:07.
bug fix for filter chain ordering
filter_speedup_filter_chain_ordering_stable_12.patch (4.1 kB) - added by skaes on 05/05/07 06:50:17.
chain ordering patch for 1-2-stable

Change History

04/30/07 18:40:42 changed by skaes

  • attachment filter_speedup.patch added.

04/30/07 19:31:54 changed by skaes

  • attachment filter_speedup_fixed.patch added.

04/30/07 19:38:38 changed by skaes

  • attachment filter_speedup_fixed2.patch added.

deleted a superflous assignment

04/30/07 20:02:45 changed by skaes

  • attachment filter_speedup_trunk.patch added.

trunk version of the patch

05/01/07 05:12:04 changed by skaes

  • milestone changed from 1.x to 1.2.4.

05/02/07 13:28:37 changed by rick

  • status changed from new to closed.
  • resolution set to fixed.

(In [6650]) apply [6649] to stable, closes #8226 [Stefan Kaes]

05/03/07 14:18:18 changed by yourcelf

  • status changed from closed to reopened.
  • type changed from enhancement to defect.
  • resolution deleted.
  • severity changed from normal to major.
  • milestone changed from 1.2.4 to 1.2 regressions.

This patch breaks EzCrypto and ActiveCrypto - not a suitable "enhancement" for stable?

ActiveCrypto uses the following:

module ActionController
  def self.append_features(base)
    super
    base.send :prepend_after_filter, :save_session_keys
    base.send :prepend_before_filter, :load_session_keys
  end
...

In my application, which also uses a "set_locale" filter, the filter chain sent to call_filters(chain, index, nesting) looks like this:

(output of "puts chain.to_yaml")

- !ruby/object:ActionController::Filters::ClassMethods::BeforeFilterProxy 
  filter: !ruby/object:ActionController::Filters::ClassMethods::SymbolFilter 
    filter: :set_locale
- !ruby/object:ActionController::Filters::ClassMethods::AfterFilterProxy 
  filter: !ruby/object:ActionController::Filters::ClassMethods::SymbolFilter 
    filter: :save_session_keys
- !ruby/object:ActionController::Filters::ClassMethods::BeforeFilterProxy 
  filter: !ruby/object:ActionController::Filters::ClassMethods::SymbolFilter 
    filter: :load_session_keys

The error I get is:

filter #<ActionController::Filters::ClassMethods::BeforeFilterProxy:0x276f290 @filter=#<ActionController::Filters::ClassMethods::SymbolFilter:0x276f2f4 @filter=:load_session_keys>> was in the wrong place!

It appears that call_filters stops processing before_filters when it encounters the after_filter, then throws the error when it encounters the unprocessed before_filter.

A very cludgy and bad fix for this in the ActiveCrypto context is to change the order in which "prepend_before_filter" and "prepend_after_filter" are called, so that "prepend_after_filter" is called _first_, and "prepend_before_filter" thus prepends the before filter before the after filter (gah).

05/03/07 14:41:56 changed by technoweenie

Can you provide a failing test case for the rails filter tests?

05/03/07 18:18:54 changed by yourcelf

Here ya go:

  class PrependingBeforeAndAfterController < ActionController::Base
    prepend_before_filter :before_all
    prepend_after_filter :after_all
    before_filter :sorta_before

    def before_all
        @ran_filter ||= []
        @ran_filter << 'before_all'
    end

    def after_all
        @ran_filter ||= []
        @ran_filter << 'after_all'
    end

    def sorta_before
        @ran_filter ||= []
        @ran_filter << 'sorta_before'
    end
    def show
    end
  end

  def test_running_prepended_before_and_after_filter
      #assert_equal 1, PrependingBeforeAndAfterController.filter_chain
      response = test_process(PrependingBeforeAndAfterController)
      assert_equal %w( before_all sorta_before after_all ), response.template.assigns["ran_filter"]
  end

Note that the response code to this test is '500'. I couldn't figure out how to get the trace and error message that shows up in the development environment to display in the test environment, but is this enough to show the problem?

05/03/07 18:36:23 changed by skaes

rick, can you add the test to trunk. I'll fix the problem tomorrow.

05/05/07 06:43:07 changed by skaes

  • attachment filter_speedup_filter_chain_ordering_trunk.patch added.

bug fix for filter chain ordering

05/05/07 06:49:42 changed by skaes

added 2 new test cases:

  • test_empty_filter_chain
  • test_running_prepended_before_and_after_filter

05/05/07 06:50:17 changed by skaes

  • attachment filter_speedup_filter_chain_ordering_stable_12.patch added.

chain ordering patch for 1-2-stable

05/06/07 05:02:02 changed by skaes

  • status changed from reopened to closed.
  • resolution set to fixed.

fixed in [6671]