activesupport 3.1.12 → 3.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- data/CHANGELOG.md +1539 -30
- data/README.rdoc +2 -2
- data/lib/active_support.rb +1 -1
- data/lib/active_support/benchmarkable.rb +13 -18
- data/lib/active_support/buffered_logger.rb +43 -55
- data/lib/active_support/cache.rb +109 -115
- data/lib/active_support/cache/file_store.rb +6 -17
- data/lib/active_support/cache/mem_cache_store.rb +10 -2
- data/lib/active_support/cache/null_store.rb +44 -0
- data/lib/active_support/cache/strategy/local_cache.rb +2 -2
- data/lib/active_support/callbacks.rb +38 -35
- data/lib/active_support/concern.rb +5 -10
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +1 -1
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
- data/lib/active_support/core_ext/array/wrap.rb +1 -1
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -2
- data/lib/active_support/core_ext/date/calculations.rb +37 -14
- data/lib/active_support/core_ext/date/freeze.rb +6 -4
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +25 -8
- data/lib/active_support/core_ext/file/atomic.rb +1 -2
- data/lib/active_support/core_ext/hash/conversions.rb +7 -25
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/io.rb +15 -0
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
- data/lib/active_support/core_ext/kernel/debugger.rb +1 -7
- data/lib/active_support/core_ext/module.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -2
- data/lib/active_support/core_ext/module/delegation.rb +32 -21
- data/lib/active_support/core_ext/module/qualified_const.rb +64 -0
- data/lib/active_support/core_ext/module/reachable.rb +1 -3
- data/lib/active_support/core_ext/module/synchronization.rb +2 -0
- data/lib/active_support/core_ext/object/blank.rb +14 -2
- data/lib/active_support/core_ext/object/inclusion.rb +17 -7
- data/lib/active_support/core_ext/object/to_json.rb +2 -2
- data/lib/active_support/core_ext/range/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/inflections.rb +44 -6
- data/lib/active_support/core_ext/string/multibyte.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +22 -25
- data/lib/active_support/core_ext/time/calculations.rb +66 -12
- data/lib/active_support/dependencies.rb +51 -52
- data/lib/active_support/file_update_checker.rb +100 -15
- data/lib/active_support/hash_with_indifferent_access.rb +5 -1
- data/lib/active_support/i18n.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +9 -4
- data/lib/active_support/inflections.rb +3 -3
- data/lib/active_support/inflector/inflections.rb +53 -92
- data/lib/active_support/inflector/methods.rb +173 -9
- data/lib/active_support/json/decoding.rb +3 -17
- data/lib/active_support/json/encoding.rb +11 -14
- data/lib/active_support/memoizable.rb +12 -1
- data/lib/active_support/message_encryptor.rb +52 -20
- data/lib/active_support/message_verifier.rb +15 -4
- data/lib/active_support/notifications.rb +87 -14
- data/lib/active_support/notifications/instrumenter.rb +1 -2
- data/lib/active_support/ordered_hash.rb +7 -3
- data/lib/active_support/tagged_logging.rb +63 -0
- data/lib/active_support/testing/assertions.rb +1 -1
- data/lib/active_support/testing/mochaing.rb +2 -2
- data/lib/active_support/testing/performance/ruby.rb +1 -1
- data/lib/active_support/testing/setup_and_teardown.rb +4 -12
- data/lib/active_support/time_with_zone.rb +6 -3
- data/lib/active_support/values/time_zone.rb +3 -7
- data/lib/active_support/version.rb +3 -3
- data/lib/active_support/xml_mini.rb +3 -3
- data/lib/active_support/xml_mini/jdom.rb +4 -10
- metadata +28 -21
- checksums.yaml +0 -7
- data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
- data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
- data/lib/active_support/core_ext/kernel/requires.rb +0 -28
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
- data/lib/active_support/secure_random.rb +0 -6
data/README.rdoc
CHANGED
@@ -8,7 +8,7 @@ outside of Rails.
|
|
8
8
|
|
9
9
|
== Download and installation
|
10
10
|
|
11
|
-
The latest version of Active Support can be installed with
|
11
|
+
The latest version of Active Support can be installed with RubyGems:
|
12
12
|
|
13
13
|
% [sudo] gem install activesupport
|
14
14
|
|
@@ -26,7 +26,7 @@ Active Support is released under the MIT license.
|
|
26
26
|
|
27
27
|
API documentation is at
|
28
28
|
|
29
|
-
* http://api.rubyonrails.
|
29
|
+
* http://api.rubyonrails.org
|
30
30
|
|
31
31
|
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
|
32
32
|
|
data/lib/active_support.rb
CHANGED
@@ -3,41 +3,36 @@ require 'active_support/core_ext/hash/keys'
|
|
3
3
|
|
4
4
|
module ActiveSupport
|
5
5
|
module Benchmarkable
|
6
|
-
# Allows you to measure the execution time of a block
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# processing method was taking too long; you could wrap it in a benchmark block.
|
6
|
+
# Allows you to measure the execution time of a block in a template and records the result to
|
7
|
+
# the log. Wrap this block around expensive operations or possible bottlenecks to get a time
|
8
|
+
# reading for the operation. For example, let's say you thought your file processing method
|
9
|
+
# was taking too long; you could wrap it in a benchmark block.
|
11
10
|
#
|
12
11
|
# <% benchmark "Process data files" do %>
|
13
12
|
# <%= expensive_files_operation %>
|
14
13
|
# <% end %>
|
15
14
|
#
|
16
|
-
# That would add something like "Process data files (345.2ms)" to the log,
|
17
|
-
#
|
15
|
+
# That would add something like "Process data files (345.2ms)" to the log, which you can then
|
16
|
+
# use to compare timings when optimizing your code.
|
18
17
|
#
|
19
|
-
# You may give an optional logger level as the :level option.
|
20
|
-
#
|
18
|
+
# You may give an optional logger level (:debug, :info, :warn, :error) as the :level option.
|
19
|
+
# The default logger level value is :info.
|
21
20
|
#
|
22
21
|
# <% benchmark "Low-level files", :level => :debug do %>
|
23
22
|
# <%= lowlevel_files_operation %>
|
24
23
|
# <% end %>
|
25
24
|
#
|
26
|
-
# Finally, you can pass true as the third argument to silence all log activity
|
27
|
-
# inside the block. This is great for boiling down a noisy block to
|
25
|
+
# Finally, you can pass true as the third argument to silence all log activity (other than the
|
26
|
+
# timing information) from inside the block. This is great for boiling down a noisy block to
|
27
|
+
# just a single statement that produces one log line:
|
28
28
|
#
|
29
29
|
# <% benchmark "Process data files", :level => :info, :silence => true do %>
|
30
30
|
# <%= expensive_and_chatty_files_operation %>
|
31
31
|
# <% end %>
|
32
32
|
def benchmark(message = "Benchmarking", options = {})
|
33
33
|
if logger
|
34
|
-
|
35
|
-
|
36
|
-
options = { :level => options, :silence => false }
|
37
|
-
else
|
38
|
-
options.assert_valid_keys(:level, :silence)
|
39
|
-
options[:level] ||= :info
|
40
|
-
end
|
34
|
+
options.assert_valid_keys(:level, :silence)
|
35
|
+
options[:level] ||= :info
|
41
36
|
|
42
37
|
result = nil
|
43
38
|
ms = Benchmark.ms { result = options[:silence] ? logger.silence { yield } : yield }
|
@@ -1,5 +1,9 @@
|
|
1
1
|
require 'thread'
|
2
|
+
require 'logger'
|
3
|
+
require 'active_support/core_ext/logger'
|
2
4
|
require 'active_support/core_ext/class/attribute_accessors'
|
5
|
+
require 'active_support/deprecation'
|
6
|
+
require 'fileutils'
|
3
7
|
|
4
8
|
module ActiveSupport
|
5
9
|
# Inspired by the buffered logger idea by Ezra
|
@@ -26,33 +30,34 @@ module ActiveSupport
|
|
26
30
|
def silence(temporary_level = ERROR)
|
27
31
|
if silencer
|
28
32
|
begin
|
29
|
-
|
30
|
-
yield
|
33
|
+
logger = self.class.new @log_dest, temporary_level
|
34
|
+
yield logger
|
31
35
|
ensure
|
32
|
-
|
36
|
+
logger.close
|
33
37
|
end
|
34
38
|
else
|
35
39
|
yield self
|
36
40
|
end
|
37
41
|
end
|
42
|
+
deprecate :silence
|
38
43
|
|
39
|
-
attr_accessor :level
|
40
44
|
attr_reader :auto_flushing
|
45
|
+
deprecate :auto_flushing
|
41
46
|
|
42
47
|
def initialize(log, level = DEBUG)
|
43
48
|
@level = level
|
44
|
-
@
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
FileUtils.mkdir_p(File.dirname(log))
|
54
|
-
@log = open_log(log, (File::WRONLY | File::APPEND | File::CREAT))
|
49
|
+
@log_dest = log
|
50
|
+
|
51
|
+
unless log.respond_to?(:write)
|
52
|
+
unless File.exist?(File.dirname(log))
|
53
|
+
ActiveSupport::Deprecation.warn(<<-eowarn)
|
54
|
+
Automatic directory creation for '#{log}' is deprecated. Please make sure the directory for your log file exists before creating the logger.
|
55
|
+
eowarn
|
56
|
+
FileUtils.mkdir_p(File.dirname(log))
|
57
|
+
end
|
55
58
|
end
|
59
|
+
|
60
|
+
@log = open_logfile log
|
56
61
|
end
|
57
62
|
|
58
63
|
def open_log(log, mode)
|
@@ -61,30 +66,32 @@ module ActiveSupport
|
|
61
66
|
open_log.sync = true
|
62
67
|
end
|
63
68
|
end
|
69
|
+
deprecate :open_log
|
70
|
+
|
71
|
+
def level
|
72
|
+
@log.level
|
73
|
+
end
|
74
|
+
|
75
|
+
def level=(l)
|
76
|
+
@log.level = l
|
77
|
+
end
|
64
78
|
|
65
79
|
def add(severity, message = nil, progname = nil, &block)
|
66
|
-
|
67
|
-
message = (message || (block && block.call) || progname).to_s
|
68
|
-
# If a newline is necessary then create a new message ending with a newline.
|
69
|
-
# Ensures that the original message is not mutated.
|
70
|
-
message = "#{message}\n" unless message[-1] == ?\n
|
71
|
-
buffer << message
|
72
|
-
auto_flush
|
73
|
-
message
|
80
|
+
@log.add(severity, message, progname, &block)
|
74
81
|
end
|
75
82
|
|
76
83
|
# Dynamically add methods such as:
|
77
84
|
# def info
|
78
85
|
# def warn
|
79
86
|
# def debug
|
80
|
-
|
87
|
+
Severity.constants.each do |severity|
|
81
88
|
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
82
89
|
def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
|
83
90
|
add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
|
84
91
|
end # end
|
85
92
|
|
86
93
|
def #{severity.downcase}? # def debug?
|
87
|
-
#{severity} >=
|
94
|
+
#{severity} >= level # DEBUG >= @level
|
88
95
|
end # end
|
89
96
|
EOT
|
90
97
|
end
|
@@ -94,44 +101,25 @@ module ActiveSupport
|
|
94
101
|
# never auto-flush. If you turn auto-flushing off, be sure to regularly
|
95
102
|
# flush the log yourself -- it will eat up memory until you do.
|
96
103
|
def auto_flushing=(period)
|
97
|
-
@auto_flushing =
|
98
|
-
case period
|
99
|
-
when true; 1
|
100
|
-
when false, nil, 0; MAX_BUFFER_SIZE
|
101
|
-
when Integer; period
|
102
|
-
else raise ArgumentError, "Unrecognized auto_flushing period: #{period.inspect}"
|
103
|
-
end
|
104
104
|
end
|
105
|
+
deprecate :auto_flushing=
|
105
106
|
|
106
107
|
def flush
|
107
|
-
|
108
|
-
|
109
|
-
@log.write(content)
|
110
|
-
end
|
108
|
+
end
|
109
|
+
deprecate :flush
|
111
110
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
111
|
+
def respond_to?(method, include_private = false)
|
112
|
+
return false if method.to_s == "flush"
|
113
|
+
super
|
116
114
|
end
|
117
115
|
|
118
116
|
def close
|
119
|
-
|
120
|
-
@log.close if @log.respond_to?(:close)
|
121
|
-
@log = nil
|
117
|
+
@log.close
|
122
118
|
end
|
123
119
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
def buffer
|
130
|
-
@buffer[Thread.current]
|
131
|
-
end
|
132
|
-
|
133
|
-
def clear_buffer
|
134
|
-
@buffer.delete(Thread.current)
|
135
|
-
end
|
120
|
+
private
|
121
|
+
def open_logfile(log)
|
122
|
+
Logger.new log
|
123
|
+
end
|
136
124
|
end
|
137
125
|
end
|
data/lib/active_support/cache.rb
CHANGED
@@ -16,8 +16,7 @@ module ActiveSupport
|
|
16
16
|
autoload :FileStore, 'active_support/cache/file_store'
|
17
17
|
autoload :MemoryStore, 'active_support/cache/memory_store'
|
18
18
|
autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
|
19
|
-
autoload :
|
20
|
-
autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store'
|
19
|
+
autoload :NullStore, 'active_support/cache/null_store'
|
21
20
|
|
22
21
|
# These options mean something to all cache implementations. Individual cache
|
23
22
|
# implementations may support additional options.
|
@@ -27,75 +26,75 @@ module ActiveSupport
|
|
27
26
|
autoload :LocalCache, 'active_support/cache/strategy/local_cache'
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
29
|
+
class << self
|
30
|
+
# Creates a new CacheStore object according to the given options.
|
31
|
+
#
|
32
|
+
# If no arguments are passed to this method, then a new
|
33
|
+
# ActiveSupport::Cache::MemoryStore object will be returned.
|
34
|
+
#
|
35
|
+
# If you pass a Symbol as the first argument, then a corresponding cache
|
36
|
+
# store class under the ActiveSupport::Cache namespace will be created.
|
37
|
+
# For example:
|
38
|
+
#
|
39
|
+
# ActiveSupport::Cache.lookup_store(:memory_store)
|
40
|
+
# # => returns a new ActiveSupport::Cache::MemoryStore object
|
41
|
+
#
|
42
|
+
# ActiveSupport::Cache.lookup_store(:mem_cache_store)
|
43
|
+
# # => returns a new ActiveSupport::Cache::MemCacheStore object
|
44
|
+
#
|
45
|
+
# Any additional arguments will be passed to the corresponding cache store
|
46
|
+
# class's constructor:
|
47
|
+
#
|
48
|
+
# ActiveSupport::Cache.lookup_store(:file_store, "/tmp/cache")
|
49
|
+
# # => same as: ActiveSupport::Cache::FileStore.new("/tmp/cache")
|
50
|
+
#
|
51
|
+
# If the first argument is not a Symbol, then it will simply be returned:
|
52
|
+
#
|
53
|
+
# ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
|
54
|
+
# # => returns MyOwnCacheStore.new
|
55
|
+
def lookup_store(*store_option)
|
56
|
+
store, *parameters = *Array.wrap(store_option).flatten
|
57
|
+
|
58
|
+
case store
|
59
|
+
when Symbol
|
60
|
+
store_class_name = store.to_s.camelize
|
61
|
+
store_class =
|
62
|
+
begin
|
63
|
+
require "active_support/cache/#{store}"
|
64
|
+
rescue LoadError => e
|
65
|
+
raise "Could not find cache store adapter for #{store} (#{e})"
|
66
|
+
else
|
67
|
+
ActiveSupport::Cache.const_get(store_class_name)
|
68
|
+
end
|
69
|
+
store_class.new(*parameters)
|
70
|
+
when nil
|
71
|
+
ActiveSupport::Cache::MemoryStore.new
|
72
|
+
else
|
73
|
+
store
|
74
|
+
end
|
74
75
|
end
|
75
|
-
end
|
76
76
|
|
77
|
-
|
78
|
-
|
77
|
+
def expand_cache_key(key, namespace = nil)
|
78
|
+
expanded_cache_key = namespace ? "#{namespace}/" : ""
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
|
81
|
+
if prefix
|
82
|
+
expanded_cache_key << "#{prefix}/"
|
83
|
+
end
|
84
|
+
|
85
|
+
expanded_cache_key << retrieve_cache_key(key)
|
86
|
+
expanded_cache_key
|
83
87
|
end
|
84
88
|
|
85
|
-
|
86
|
-
if key.respond_to?(:cache_key)
|
87
|
-
key.cache_key
|
88
|
-
elsif key.is_a?(Array)
|
89
|
-
if key.size > 1
|
90
|
-
key.collect { |element| expand_cache_key(element) }.to_param
|
91
|
-
else
|
92
|
-
key.first.to_param
|
93
|
-
end
|
94
|
-
elsif key
|
95
|
-
key.to_param
|
96
|
-
end.to_s
|
89
|
+
private
|
97
90
|
|
98
|
-
|
91
|
+
def retrieve_cache_key(key)
|
92
|
+
case
|
93
|
+
when key.respond_to?(:cache_key) then key.cache_key
|
94
|
+
when key.is_a?(Array) then ['Array', *key.map { |element| retrieve_cache_key(element) }].to_param
|
95
|
+
else key.to_param
|
96
|
+
end.to_s
|
97
|
+
end
|
99
98
|
end
|
100
99
|
|
101
100
|
# An abstract cache store class. There are multiple cache store
|
@@ -116,31 +115,32 @@ module ActiveSupport
|
|
116
115
|
# cache.read("city") # => "Duckburgh"
|
117
116
|
#
|
118
117
|
# Keys are always translated into Strings and are case sensitive. When an
|
119
|
-
# object is specified as a key
|
120
|
-
#
|
121
|
-
# Arrays can be used as keys. The
|
122
|
-
#
|
118
|
+
# object is specified as a key and has a +cache_key+ method defined, this
|
119
|
+
# method will be called to define the key. Otherwise, the +to_param+
|
120
|
+
# method will be called. Hashes and Arrays can also be used as keys. The
|
121
|
+
# elements will be delimited by slashes, and the elements within a Hash
|
122
|
+
# will be sorted by key so they are consistent.
|
123
123
|
#
|
124
124
|
# cache.read("city") == cache.read(:city) # => true
|
125
125
|
#
|
126
126
|
# Nil values can be cached.
|
127
127
|
#
|
128
|
-
# If your cache is on a shared infrastructure, you can define a namespace
|
129
|
-
# your cache entries. If a namespace is defined, it will be prefixed on
|
130
|
-
# key. The namespace can be either a static value or a Proc. If it
|
131
|
-
# will be invoked when each key is evaluated so that you can
|
132
|
-
# to invalidate keys.
|
128
|
+
# If your cache is on a shared infrastructure, you can define a namespace
|
129
|
+
# for your cache entries. If a namespace is defined, it will be prefixed on
|
130
|
+
# to every key. The namespace can be either a static value or a Proc. If it
|
131
|
+
# is a Proc, it will be invoked when each key is evaluated so that you can
|
132
|
+
# use application logic to invalidate keys.
|
133
133
|
#
|
134
134
|
# cache.namespace = lambda { @last_mod_time } # Set the namespace to a variable
|
135
135
|
# @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
|
136
136
|
#
|
137
137
|
#
|
138
|
-
# Caches can also store values in a compressed format to save space and
|
139
|
-
# time spent sending data. Since there is
|
140
|
-
# enough to warrant compression. To turn on compression either pass
|
141
|
-
# <tt>:compress => true</tt> in the initializer or to +fetch+
|
142
|
-
# To specify the threshold at which to compress values, set
|
143
|
-
# <tt>:compress_threshold</tt
|
138
|
+
# Caches can also store values in a compressed format to save space and
|
139
|
+
# reduce time spent sending data. Since there is overhead, values must be
|
140
|
+
# large enough to warrant compression. To turn on compression either pass
|
141
|
+
# <tt>:compress => true</tt> in the initializer or as an option to +fetch+
|
142
|
+
# or +write+. To specify the threshold at which to compress values, set the
|
143
|
+
# <tt>:compress_threshold</tt> option. The default threshold is 16K.
|
144
144
|
class Store
|
145
145
|
|
146
146
|
cattr_accessor :logger, :instance_writer => true
|
@@ -150,7 +150,7 @@ module ActiveSupport
|
|
150
150
|
|
151
151
|
# Create a new cache. The options will be passed to any write method calls except
|
152
152
|
# for :namespace which can be used to set the global namespace for the cache.
|
153
|
-
def initialize
|
153
|
+
def initialize(options = nil)
|
154
154
|
@options = options ? options.dup : {}
|
155
155
|
end
|
156
156
|
|
@@ -180,11 +180,11 @@ module ActiveSupport
|
|
180
180
|
# Fetches data from the cache, using the given key. If there is data in
|
181
181
|
# the cache with the given key, then that data is returned.
|
182
182
|
#
|
183
|
-
# If there is no such data in the cache (a cache miss
|
184
|
-
#
|
185
|
-
#
|
186
|
-
#
|
187
|
-
#
|
183
|
+
# If there is no such data in the cache (a cache miss), then nil will be
|
184
|
+
# returned. However, if a block has been passed, that block will be run
|
185
|
+
# in the event of a cache miss. The return value of the block will be
|
186
|
+
# written to the cache under the given cache key, and that return value
|
187
|
+
# will be returned.
|
188
188
|
#
|
189
189
|
# cache.write("today", "Monday")
|
190
190
|
# cache.fetch("today") # => "Monday"
|
@@ -205,10 +205,11 @@ module ActiveSupport
|
|
205
205
|
# in a compressed format.
|
206
206
|
#
|
207
207
|
#
|
208
|
-
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
|
209
|
-
# support auto
|
210
|
-
# be specified as an option to the
|
211
|
-
#
|
208
|
+
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
|
209
|
+
# All caches support auto-expiring content after a specified number of
|
210
|
+
# seconds. This value can be specified as an option to the constructor
|
211
|
+
# (in which case all entries will be affected), or it can be supplied to
|
212
|
+
# the +fetch+ or +write+ method to effect just one entry.
|
212
213
|
#
|
213
214
|
# cache = ActiveSupport::Cache::MemoryStore.new(:expires_in => 5.minutes)
|
214
215
|
# cache.write(key, value, :expires_in => 1.minute) # Set a lower value for one entry
|
@@ -538,11 +539,11 @@ module ActiveSupport
|
|
538
539
|
# Create an entry with internal attributes set. This method is intended to be
|
539
540
|
# used by implementations that store cache entries in a native format instead
|
540
541
|
# of as serialized Ruby objects.
|
541
|
-
def create
|
542
|
+
def create(raw_value, created_at, options = {})
|
542
543
|
entry = new(nil)
|
543
544
|
entry.instance_variable_set(:@value, raw_value)
|
544
545
|
entry.instance_variable_set(:@created_at, created_at.to_f)
|
545
|
-
entry.instance_variable_set(:@compressed,
|
546
|
+
entry.instance_variable_set(:@compressed, options[:compressed])
|
546
547
|
entry.instance_variable_set(:@expires_in, options[:expires_in])
|
547
548
|
entry
|
548
549
|
end
|
@@ -555,15 +556,14 @@ module ActiveSupport
|
|
555
556
|
@expires_in = options[:expires_in]
|
556
557
|
@expires_in = @expires_in.to_f if @expires_in
|
557
558
|
@created_at = Time.now.to_f
|
558
|
-
|
559
|
-
|
560
|
-
|
559
|
+
if value.nil?
|
560
|
+
@value = nil
|
561
|
+
else
|
562
|
+
@value = Marshal.dump(value)
|
563
|
+
if should_compress?(@value, options)
|
564
|
+
@value = Zlib::Deflate.deflate(@value)
|
561
565
|
@compressed = true
|
562
|
-
else
|
563
|
-
@value = value
|
564
566
|
end
|
565
|
-
else
|
566
|
-
@value = nil
|
567
567
|
end
|
568
568
|
end
|
569
569
|
|
@@ -574,12 +574,11 @@ module ActiveSupport
|
|
574
574
|
|
575
575
|
# Get the value stored in the cache.
|
576
576
|
def value
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
val
|
577
|
+
# If the original value was exactly false @value is still true because
|
578
|
+
# it is marshalled and eventually compressed. Both operations yield
|
579
|
+
# strings.
|
580
|
+
if @value
|
581
|
+
Marshal.load(compressed? ? Zlib::Inflate.inflate(@value) : @value)
|
583
582
|
end
|
584
583
|
end
|
585
584
|
|
@@ -612,21 +611,16 @@ module ActiveSupport
|
|
612
611
|
def size
|
613
612
|
if @value.nil?
|
614
613
|
0
|
615
|
-
elsif @value.respond_to?(:bytesize)
|
616
|
-
@value.bytesize
|
617
614
|
else
|
618
|
-
|
615
|
+
@value.bytesize
|
619
616
|
end
|
620
617
|
end
|
621
618
|
|
622
619
|
private
|
623
|
-
def should_compress?(
|
624
|
-
if options[:compress]
|
625
|
-
|
626
|
-
|
627
|
-
serialized_value = value.is_a?(String) ? value : Marshal.dump(value)
|
628
|
-
return true if serialized_value.size >= compress_threshold
|
629
|
-
end
|
620
|
+
def should_compress?(serialized_value, options)
|
621
|
+
if options[:compress]
|
622
|
+
compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT
|
623
|
+
return true if serialized_value.size >= compress_threshold
|
630
624
|
end
|
631
625
|
false
|
632
626
|
end
|