Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
51c24ae3
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
51c24ae3
编写于
10月 29, 2009
作者:
Y
Yehuda Katz
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Caching refactoring
上级
a288b74f
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
98 addition
and
93 deletion
+98
-93
actionpack/lib/action_controller/caching.rb
actionpack/lib/action_controller/caching.rb
+19
-13
actionpack/lib/action_controller/caching/actions.rb
actionpack/lib/action_controller/caching/actions.rb
+66
-69
actionpack/lib/action_controller/caching/sweeping.rb
actionpack/lib/action_controller/caching/sweeping.rb
+1
-1
actionpack/lib/action_controller/metal/compatibility.rb
actionpack/lib/action_controller/metal/compatibility.rb
+5
-3
actionpack/lib/action_dispatch/http/request.rb
actionpack/lib/action_dispatch/http/request.rb
+1
-5
actionpack/test/controller/caching_test.rb
actionpack/test/controller/caching_test.rb
+6
-2
未找到文件。
actionpack/lib/action_controller/caching.rb
浏览文件 @
51c24ae3
...
...
@@ -3,26 +3,30 @@
require
'set'
module
ActionController
#:nodoc:
# Caching is a cheap way of speeding up slow applications by keeping the result of calculations, renderings, and database calls
# around for subsequent requests. Action Controller affords you three approaches in varying levels of granularity: Page, Action, Fragment.
# Caching is a cheap way of speeding up slow applications by keeping the result of
# calculations, renderings, and database calls around for subsequent requests.
# Action Controller affords you three approaches in varying levels of granularity:
# Page, Action, Fragment.
#
# You can read more about each approach and the sweeping assistance by clicking the modules below.
#
# Note: To turn off all caching and sweeping, set Base.perform_caching = false.
# You can read more about each approach and the sweeping assistance by clicking the
# modules below.
#
# Note: To turn off all caching and sweeping, set
# config.action_controller.perform_caching = false.
#
# == Caching stores
#
# All the caching stores from ActiveSupport::Cache are available to be used as backends for Action Controller caching. This setting only
# affects action and fragment caching as page caching is always written to disk.
# All the caching stores from ActiveSupport::Cache are available to be used as backends
# for Action Controller caching. This setting only affects action and fragment caching
# as page caching is always written to disk.
#
# Configuration examples (MemoryStore is the default):
#
#
ActionController::Base
.cache_store = :memory_store
#
ActionController::Base
.cache_store = :file_store, "/path/to/cache/directory"
#
ActionController::Base
.cache_store = :drb_store, "druby://localhost:9192"
#
ActionController::Base
.cache_store = :mem_cache_store, "localhost"
#
ActionController::Base
.cache_store = MyOwnStore.new("parameter")
#
config.action_controller
.cache_store = :memory_store
#
config.action_controller
.cache_store = :file_store, "/path/to/cache/directory"
#
config.action_controller
.cache_store = :drb_store, "druby://localhost:9192"
#
config.action_controller
.cache_store = :mem_cache_store, "localhost"
#
config.action_controller
.cache_store = MyOwnStore.new("parameter")
module
Caching
extend
ActiveSupport
::
Concern
...
...
@@ -46,8 +50,10 @@ def self.cache_store=(store_option)
@@perform_caching
=
true
cattr_accessor
:perform_caching
end
def
self
.
cache_configured?
module
ClassMethods
def
cache_configured?
perform_caching
&&
cache_store
end
end
...
...
actionpack/lib/action_controller/caching/actions.rb
浏览文件 @
51c24ae3
...
...
@@ -2,10 +2,12 @@
module
ActionController
#:nodoc:
module
Caching
# Action caching is similar to page caching by the fact that the entire output of the response is
# cached, but unlike page caching, every request still goes through the Action Pack. The key benefit
# of this is that filters are run before the cache is served, which allows for authentication and other
# restrictions on whether someone is allowed to see the cache. Example:
# Action caching is similar to page caching by the fact that the entire
# output of the response is cached, but unlike page caching, every
# request still goes through the Action Pack. The key benefit
# of this is that filters are run before the cache is served, which
# allows for authentication and other restrictions on whether someone
# is allowed to see the cache. Example:
#
# class ListsController < ApplicationController
# before_filter :authenticate, :except => :public
...
...
@@ -13,55 +15,65 @@ module Caching
# caches_action :index, :show, :feed
# end
#
# In this example, the public action doesn't require authentication, so it's possible to use the faster
# page caching method. But both the show and feed action are to be shielded behind the authenticate
# In this example, the public action doesn't require authentication,
# so it's possible to use the faster page caching method. But both
# the show and feed action are to be shielded behind the authenticate
# filter, so we need to implement those as action caches.
#
# Action caching internally uses the fragment caching and an around filter to do the job. The fragment
# cache is named according to both the current host and the path. So a page that is accessed at
# Action caching internally uses the fragment caching and an around
# filter to do the job. The fragment cache is named according to both
# the current host and the path. So a page that is accessed at
# http://david.somewhere.com/lists/show/1 will result in a fragment named
# "david.somewhere.com/lists/show/1". This allows the cacher to
differentiate between
# "david.somewhere.com/lists/" and
# "jamis.somewhere.com/lists/" -- which is a helpful way of assisting
the subdomain-as-account-key
# pattern.
# "david.somewhere.com/lists/show/1". This allows the cacher to
#
differentiate between
"david.somewhere.com/lists/" and
# "jamis.somewhere.com/lists/" -- which is a helpful way of assisting
#
the subdomain-as-account-key
pattern.
#
# Different representations of the same resource, e.g. <tt>http://david.somewhere.com/lists</tt> and
# Different representations of the same resource, e.g.
# <tt>http://david.somewhere.com/lists</tt> and
# <tt>http://david.somewhere.com/lists.xml</tt>
# are treated like separate requests and so are cached separately. Keep in mind when expiring an
# action cache that <tt>:action => 'lists'</tt> is not the same as
# are treated like separate requests and so are cached separately.
# Keep in mind when expiring an action cache that
# <tt>:action => 'lists'</tt> is not the same as
# <tt>:action => 'list', :format => :xml</tt>.
#
# You can set modify the default action cache path by passing a :cache_path option. This will be
# passed directly to ActionCachePath.path_for. This is handy for actions with multiple possible
# routes that should be cached differently. If a block is given, it is called with the current
# controller instance.
# You can set modify the default action cache path by passing a
# :cache_path option. This will be passed directly to
# ActionCachePath.path_for. This is handy for actions with multiple
# possible routes that should be cached differently. If a block is
# given, it is called with the current controller instance.
#
# And you can also use :if (or :unless) to pass a Proc that
specifies when the action should
# be cached.
# And you can also use :if (or :unless) to pass a Proc that
#
specifies when the action should
be cached.
#
# Finally, if you are using memcached, you can also pass :expires_in.
#
# class ListsController < ApplicationController
# before_filter :authenticate, :except => :public
# caches_page :public
# caches_action :index, :if => proc { |c| !c.request.format.json? } # cache if is not a JSON request
# caches_action :show, :cache_path => { :project => 1 }, :expires_in => 1.hour
# caches_action :feed, :cache_path => proc { |controller|
# controller.params[:user_id] ?
# controller.send(:user_list_url, controller.params[:user_id], controller.params[:id]) :
# controller.send(:list_url, controller.params[:id]) }
# caches_action :index, :if => proc do |c|
# !c.request.format.json? # cache if is not a JSON request
# end
#
# caches_action :show, :cache_path => { :project => 1 },
# :expires_in => 1.hour
#
# caches_action :feed, :cache_path => proc do |controller|
# if controller.params[:user_id]
# controller.send(:user_list_url,
# controller.params[:user_id], controller.params[:id])
# else
# controller.send(:list_url, controller.params[:id])
# end
# end
# end
#
# If you pass :layout => false, it will only cache your action
content. It is useful when your
# layout has dynamic information.
# If you pass :layout => false, it will only cache your action
#
content. It is useful when your
layout has dynamic information.
#
module
Actions
extend
ActiveSupport
::
Concern
included
do
attr_accessor
:rendered_action_cache
,
:action_cache_path
end
module
ClassMethods
# Declares that +actions+ should be cached.
# See ActionController::Caching::Actions for details.
...
...
@@ -76,11 +88,7 @@ def caches_action(*actions)
end
def
_render_cache_fragment
(
cache
,
extension
,
layout
)
self
.
rendered_action_cache
=
true
response
.
content_type
=
Mime
[
extension
].
to_s
if
extension
options
=
{
:text
=>
cache
}
options
.
merge!
(
:layout
=>
true
)
if
layout
render
options
render
:text
=>
cache
,
:layout
=>
layout
,
:content_type
=>
Mime
[
extension
||
:html
]
end
def
_save_fragment
(
name
,
layout
,
options
)
...
...
@@ -90,17 +98,17 @@ def _save_fragment(name, layout, options)
write_fragment
(
name
,
content
,
options
)
end
protected
def
expire_action
(
options
=
{})
return
unless
cache_configured?
protected
def
expire_action
(
options
=
{})
return
unless
cache_configured?
actions
=
options
[
:action
]
if
actions
.
is_a?
(
Array
)
actions
.
each
{
|
action
|
expire_action
(
options
.
merge
(
:action
=>
action
))
}
else
expire_fragment
(
ActionCachePath
.
path_for
(
self
,
options
,
false
))
end
actions
=
options
[
:action
]
if
actions
.
is_a?
(
Array
)
actions
.
each
{
|
action
|
expire_action
(
options
.
merge
(
:action
=>
action
))
}
else
expire_fragment
(
ActionCachePath
.
new
(
self
,
options
,
false
).
path
)
end
end
class
ActionCacheFilter
#:nodoc:
def
initialize
(
options
,
&
block
)
...
...
@@ -109,7 +117,12 @@ def initialize(options, &block)
end
def
filter
(
controller
)
path_options
=
@cache_path
.
respond_to?
(
:call
)
?
@cache_path
.
call
(
controller
)
:
@cache_path
path_options
=
if
@cache_path
.
respond_to?
(
:call
)
controller
.
instance_exec
(
controller
,
&
@cache_path
)
else
@cache_path
end
cache_path
=
ActionCachePath
.
new
(
controller
,
path_options
||
{})
if
cache
=
controller
.
read_fragment
(
cache_path
.
path
,
@store_options
)
...
...
@@ -124,41 +137,25 @@ def filter(controller)
class
ActionCachePath
attr_reader
:path
,
:extension
class
<<
self
def
path_for
(
controller
,
options
,
infer_extension
=
true
)
new
(
controller
,
options
,
infer_extension
).
path
end
end
# If +infer_extension+ is true, the cache path extension is looked up from the request's
# path & format. This is desirable when reading and writing the cache, but not when
# expiring the cache - expire_action should expire the same files regardless of the
# request format.
def
initialize
(
controller
,
options
=
{},
infer_extension
=
true
)
if
infer_extension
extract_extension
(
controller
.
request
)
options
=
options
.
reverse_merge
(
:format
=>
@extension
)
if
options
.
is_a?
(
Hash
)
@extension
=
controller
.
params
[
:format
]
options
.
reverse_merge!
(
:format
=>
@extension
)
if
options
.
is_a?
(
Hash
)
end
path
=
controller
.
url_for
(
options
).
split
(
'://'
).
last
normalize!
(
path
)
add_extension!
(
path
,
@extension
)
@path
=
URI
.
unescape
(
path
)
path
=
controller
.
url_for
(
options
).
split
(
%r{://}
).
last
@path
=
normalize!
(
path
)
end
private
def
normalize!
(
path
)
path
<<
'index'
if
path
[
-
1
]
==
?/
end
def
add_extension!
(
path
,
extension
)
path
<<
".
#{
extension
}
"
if
extension
and
!
path
.
ends_with?
(
extension
)
end
def
extract_extension
(
request
)
# Don't want just what comes after the last '.' to accommodate multi part extensions
# such as tar.gz.
@extension
=
request
.
path
[
/^[^.]+\.(.+)$/
,
1
]
||
request
.
cache_format
URI
.
unescape
(
path
)
end
end
end
...
...
actionpack/lib/action_controller/caching/sweeping.rb
浏览文件 @
51c24ae3
...
...
@@ -70,7 +70,7 @@ def after(controller)
protected
# gets the action cache path for the given options.
def
action_path_for
(
options
)
Action
Controller
::
Caching
::
Actions
::
ActionCachePath
.
path_for
(
controller
,
options
)
Action
s
::
ActionCachePath
.
new
(
controller
,
options
).
path
end
# Retrieve instance variables set in the controller.
...
...
actionpack/lib/action_controller/metal/compatibility.rb
浏览文件 @
51c24ae3
...
...
@@ -25,9 +25,11 @@ class << self
# cattr_reader :protected_instance_variables
cattr_accessor
:protected_instance_variables
self
.
protected_instance_variables
=
%w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
@action_name @before_filter_chain_aborted @action_cache_path @_headers @_params
@_flash @_response)
self
.
protected_instance_variables
=
%w(@assigns @performed_redirect @performed_render
@variables_added @request_origin @url
@parent_controller @action_name
@before_filter_chain_aborted @_headers @_params
@_flash @_response)
# Indicates whether or not optimise the generated named
# route helper methods
...
...
actionpack/lib/action_dispatch/http/request.rb
浏览文件 @
51c24ae3
...
...
@@ -98,7 +98,7 @@ def content_type
end
def
forgery_whitelisted?
method
==
:get
||
xhr?
||
!
(
!
content_type
.
nil?
&&
content_type
.
verify_request?
)
method
==
:get
||
xhr?
||
content_type
.
nil?
||
!
content_type
.
verify_request?
end
def
media_type
...
...
@@ -205,10 +205,6 @@ def template_format
end
end
def
cache_format
parameters
[
:format
]
end
# Returns true if the request's "X-Requested-With" header contains
# "XMLHttpRequest". (The Prototype Javascript library sends this header with
# every Ajax request.)
...
...
actionpack/test/controller/caching_test.rb
浏览文件 @
51c24ae3
...
...
@@ -228,12 +228,16 @@ def url_for(*args)
@mock_url_for
end
def
params
request
.
parameters
end
def
request
mocked_path
=
@mock_path
Object
.
new
.
instance_eval
(
<<-
EVAL
)
def path; '
#{
@mock_path
}
' end
def format; 'all' end
def
cache_format; nil
end
def
parameters; {:format => nil};
end
self
EVAL
end
...
...
@@ -466,7 +470,7 @@ def test_empty_path_is_normalized
@mock_controller
.
mock_url_for
=
'http://example.org/'
@mock_controller
.
mock_path
=
'/'
assert_equal
'example.org/index'
,
@path_class
.
path_for
(
@mock_controller
,
{})
assert_equal
'example.org/index'
,
@path_class
.
new
(
@mock_controller
,
{}).
path
end
def
test_file_extensions
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录