activesupport 3.0.pre → 3.0.0.rc
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 +121 -1
- data/README.rdoc +33 -0
- data/lib/active_support.rb +42 -4
- data/lib/active_support/backtrace_cleaner.rb +31 -9
- data/lib/active_support/benchmarkable.rb +1 -0
- data/lib/active_support/buffered_logger.rb +5 -2
- data/lib/active_support/builder.rb +6 -0
- data/lib/active_support/cache.rb +454 -84
- data/lib/active_support/cache/compressed_mem_cache_store.rb +6 -13
- data/lib/active_support/cache/file_store.rb +140 -41
- data/lib/active_support/cache/mem_cache_store.rb +121 -76
- data/lib/active_support/cache/memory_store.rb +127 -27
- data/lib/active_support/cache/strategy/local_cache.rb +111 -58
- data/lib/active_support/cache/synchronized_memory_store.rb +2 -38
- data/lib/active_support/callbacks.rb +105 -76
- data/lib/active_support/configurable.rb +19 -18
- 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/conversions.rb +29 -54
- data/lib/active_support/core_ext/array/extract_options.rb +16 -1
- data/lib/active_support/core_ext/array/grouping.rb +1 -1
- data/lib/active_support/core_ext/array/random_access.rb +26 -5
- data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +13 -9
- data/lib/active_support/core_ext/benchmark.rb +0 -12
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +2 -0
- data/lib/active_support/core_ext/class.rb +2 -1
- data/lib/active_support/core_ext/class/attribute.rb +67 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +33 -27
- data/lib/active_support/core_ext/class/delegating_attributes.rb +35 -41
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +23 -14
- data/lib/active_support/core_ext/class/subclasses.rb +50 -0
- data/lib/active_support/core_ext/date/calculations.rb +35 -12
- data/lib/active_support/core_ext/date/conversions.rb +5 -5
- data/lib/active_support/core_ext/date/zones.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +24 -5
- data/lib/active_support/core_ext/date_time/zones.rb +4 -0
- data/lib/active_support/core_ext/enumerable.rb +5 -9
- data/lib/active_support/core_ext/exception.rb +0 -47
- data/lib/active_support/core_ext/file.rb +1 -0
- data/lib/active_support/core_ext/file/atomic.rb +3 -2
- data/lib/active_support/core_ext/file/path.rb +5 -0
- data/lib/active_support/core_ext/float/rounding.rb +3 -2
- data/lib/active_support/core_ext/hash/conversions.rb +65 -145
- data/lib/active_support/core_ext/hash/deep_merge.rb +6 -7
- data/lib/active_support/core_ext/hash/except.rb +8 -1
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -0
- data/lib/active_support/core_ext/hash/keys.rb +10 -11
- data/lib/active_support/core_ext/hash/slice.rb +6 -0
- data/lib/active_support/core_ext/integer.rb +1 -1
- data/lib/active_support/core_ext/integer/multiple.rb +6 -0
- data/lib/active_support/core_ext/kernel.rb +1 -1
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -1
- data/lib/active_support/core_ext/kernel/requires.rb +2 -2
- data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
- data/lib/active_support/core_ext/load_error.rb +17 -30
- data/lib/active_support/core_ext/logger.rb +2 -40
- data/lib/active_support/core_ext/module.rb +5 -3
- data/lib/active_support/core_ext/module/aliasing.rb +1 -1
- data/lib/active_support/core_ext/module/anonymous.rb +24 -0
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +20 -22
- data/lib/active_support/core_ext/module/delegation.rb +21 -10
- data/lib/active_support/core_ext/module/introspection.rb +8 -8
- data/lib/active_support/core_ext/module/method_names.rb +14 -0
- data/lib/active_support/core_ext/module/reachable.rb +10 -0
- data/lib/active_support/core_ext/module/remove_method.rb +11 -0
- data/lib/active_support/core_ext/module/synchronization.rb +2 -1
- data/lib/active_support/core_ext/name_error.rb +3 -1
- data/lib/active_support/core_ext/object.rb +5 -3
- data/lib/active_support/core_ext/object/blank.rb +20 -2
- data/lib/active_support/core_ext/object/conversions.rb +2 -16
- data/lib/active_support/core_ext/object/duplicable.rb +23 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +0 -7
- data/lib/active_support/core_ext/object/to_json.rb +19 -0
- data/lib/active_support/core_ext/object/to_param.rb +49 -0
- data/lib/active_support/core_ext/object/to_query.rb +27 -0
- data/lib/active_support/core_ext/object/with_options.rb +2 -0
- data/lib/active_support/core_ext/proc.rb +4 -4
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/regexp.rb +0 -22
- data/lib/active_support/core_ext/rexml.rb +4 -1
- data/lib/active_support/core_ext/string.rb +3 -2
- data/lib/active_support/core_ext/string/access.rb +4 -2
- data/lib/active_support/core_ext/string/conversions.rb +28 -1
- data/lib/active_support/core_ext/string/encoding.rb +11 -0
- data/lib/active_support/core_ext/string/exclude.rb +6 -0
- data/lib/active_support/core_ext/string/filters.rb +29 -0
- data/lib/active_support/core_ext/string/inflections.rb +12 -12
- data/lib/active_support/core_ext/string/interpolation.rb +2 -92
- data/lib/active_support/core_ext/string/multibyte.rb +16 -19
- data/lib/active_support/core_ext/string/output_safety.rb +101 -35
- data/lib/active_support/core_ext/string/starts_ends_with.rb +0 -14
- data/lib/active_support/core_ext/string/xchar.rb +1 -1
- data/lib/active_support/core_ext/time/calculations.rb +14 -7
- data/lib/active_support/core_ext/time/conversions.rb +1 -0
- data/lib/active_support/core_ext/time/marshal.rb +56 -0
- data/lib/active_support/core_ext/time/zones.rb +2 -5
- data/lib/active_support/core_ext/uri.rb +10 -4
- data/lib/active_support/dependencies.rb +200 -197
- data/lib/active_support/dependencies/autoload.rb +50 -0
- data/lib/active_support/deprecation/behaviors.rb +13 -9
- data/lib/active_support/deprecation/method_wrappers.rb +10 -9
- data/lib/active_support/deprecation/proxy_wrappers.rb +7 -0
- data/lib/active_support/deprecation/reporting.rb +5 -3
- data/lib/active_support/descendants_tracker.rb +43 -0
- data/lib/active_support/duration.rb +8 -4
- data/lib/active_support/file_update_checker.rb +36 -0
- data/lib/active_support/hash_with_indifferent_access.rb +9 -1
- data/lib/active_support/i18n.rb +9 -0
- data/lib/active_support/i18n_railtie.rb +81 -0
- data/lib/active_support/inflections.rb +1 -1
- data/lib/active_support/inflector.rb +4 -407
- data/lib/active_support/inflector/inflections.rb +211 -0
- data/lib/active_support/inflector/methods.rb +151 -0
- data/lib/active_support/inflector/transliterate.rb +97 -0
- data/lib/active_support/json/backends/jsongem.rb +12 -9
- data/lib/active_support/json/backends/yajl.rb +40 -0
- data/lib/active_support/json/backends/yaml.rb +1 -1
- data/lib/active_support/json/decoding.rb +17 -2
- data/lib/active_support/json/encoding.rb +48 -31
- data/lib/active_support/json/variable.rb +2 -4
- data/lib/active_support/lazy_load_hooks.rb +27 -0
- data/lib/active_support/locale/en.yml +5 -2
- data/lib/active_support/log_subscriber.rb +123 -0
- data/lib/active_support/log_subscriber/test_helper.rb +99 -0
- data/lib/active_support/memoizable.rb +1 -1
- data/lib/active_support/message_encryptor.rb +1 -0
- data/lib/active_support/message_verifier.rb +2 -1
- data/lib/active_support/multibyte.rb +8 -23
- data/lib/active_support/multibyte/chars.rb +213 -446
- data/lib/active_support/multibyte/unicode.rb +392 -0
- data/lib/active_support/multibyte/utils.rb +6 -7
- data/lib/active_support/notifications.rb +29 -122
- data/lib/active_support/notifications/fanout.rb +61 -0
- data/lib/active_support/notifications/instrumenter.rb +54 -0
- data/lib/active_support/ordered_hash.rb +59 -14
- data/lib/active_support/ordered_options.rb +6 -0
- data/lib/active_support/railtie.rb +60 -0
- data/lib/active_support/rescuable.rb +7 -4
- data/lib/active_support/ruby/shim.rb +4 -6
- data/lib/active_support/test_case.rb +2 -7
- data/lib/active_support/testing/assertions.rb +15 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/isolation.rb +64 -17
- data/lib/active_support/testing/performance.rb +306 -335
- data/lib/active_support/testing/setup_and_teardown.rb +51 -29
- data/lib/active_support/time.rb +24 -3
- data/lib/active_support/time_with_zone.rb +10 -14
- data/lib/active_support/values/time_zone.rb +192 -234
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -2
- data/lib/active_support/whiny_nil.rb +9 -7
- data/lib/active_support/xml_mini.rb +130 -1
- data/lib/active_support/xml_mini/jdom.rb +2 -0
- data/lib/active_support/xml_mini/libxml.rb +23 -86
- data/lib/active_support/xml_mini/libxmlsax.rb +85 -0
- data/lib/active_support/xml_mini/nokogiri.rb +27 -24
- data/lib/active_support/xml_mini/nokogirisax.rb +83 -0
- data/lib/active_support/xml_mini/rexml.rb +8 -2
- metadata +62 -195
- data/README +0 -43
- data/lib/active_support/autoload.rb +0 -28
- data/lib/active_support/core_ext/boolean.rb +0 -1
- data/lib/active_support/core_ext/boolean/conversions.rb +0 -11
- data/lib/active_support/core_ext/class/removal.rb +0 -53
- data/lib/active_support/core_ext/date.rb +0 -7
- data/lib/active_support/core_ext/date_time.rb +0 -5
- data/lib/active_support/core_ext/integer/even_odd.rb +0 -16
- data/lib/active_support/core_ext/kernel/daemonizing.rb +0 -7
- data/lib/active_support/core_ext/module/inclusion.rb +0 -30
- data/lib/active_support/core_ext/module/loading.rb +0 -23
- data/lib/active_support/core_ext/nil.rb +0 -1
- data/lib/active_support/core_ext/nil/conversions.rb +0 -5
- data/lib/active_support/core_ext/object/extending.rb +0 -80
- data/lib/active_support/core_ext/object/metaclass.rb +0 -13
- data/lib/active_support/core_ext/object/misc.rb +0 -3
- data/lib/active_support/core_ext/object/returning.rb +0 -42
- data/lib/active_support/core_ext/object/tap.rb +0 -16
- data/lib/active_support/core_ext/string/bytesize.rb +0 -5
- data/lib/active_support/core_ext/string/iterators.rb +0 -13
- data/lib/active_support/core_ext/symbol.rb +0 -1
- data/lib/active_support/core_ext/symbol/to_proc.rb +0 -14
- data/lib/active_support/core_ext/time.rb +0 -10
- data/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +0 -22
- data/lib/active_support/deprecated_callbacks.rb +0 -283
- data/lib/active_support/multibyte/unicode_database.rb +0 -71
- data/lib/active_support/vendor.rb +0 -16
- data/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb +0 -113
- data/lib/active_support/vendor/builder-2.1.2/lib/builder.rb +0 -13
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb +0 -20
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb +0 -250
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb +0 -115
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb +0 -139
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb +0 -63
- data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb +0 -328
- data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +0 -20
- data/lib/active_support/vendor/i18n-0.1.3/README.textile +0 -20
- data/lib/active_support/vendor/i18n-0.1.3/Rakefile +0 -5
- data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +0 -27
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb +0 -204
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +0 -215
- data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb +0 -53
- data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +0 -5
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +0 -99
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -124
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +0 -1
- data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +0 -3
- data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -567
- data/lib/active_support/vendor/memcache-client-1.7.5/lib/memcache.rb +0 -1133
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo.rb +0 -33
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone.rb +0 -47
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone_info.rb +0 -228
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Algiers.rb +0 -55
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Cairo.rb +0 -219
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Casablanca.rb +0 -42
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Harare.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Johannesburg.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Monrovia.rb +0 -22
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Nairobi.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +0 -166
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/San_Juan.rb +0 -86
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Bogota.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Caracas.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chicago.rb +0 -283
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chihuahua.rb +0 -136
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Denver.rb +0 -204
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Godthab.rb +0 -161
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Guatemala.rb +0 -27
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Halifax.rb +0 -274
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Indiana/Indianapolis.rb +0 -149
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Juneau.rb +0 -194
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/La_Paz.rb +0 -22
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Lima.rb +0 -35
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Los_Angeles.rb +0 -232
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mazatlan.rb +0 -139
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mexico_City.rb +0 -144
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Monterrey.rb +0 -131
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/New_York.rb +0 -282
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Phoenix.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Regina.rb +0 -74
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Santiago.rb +0 -205
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Sao_Paulo.rb +0 -171
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/St_Johns.rb +0 -288
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Tijuana.rb +0 -196
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Almaty.rb +0 -67
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baghdad.rb +0 -73
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baku.rb +0 -161
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Bangkok.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Chongqing.rb +0 -33
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Colombo.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Dhaka.rb +0 -27
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Hong_Kong.rb +0 -87
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Irkutsk.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jakarta.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jerusalem.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kabul.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kamchatka.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Karachi.rb +0 -32
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kathmandu.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kolkata.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Krasnoyarsk.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuala_Lumpur.rb +0 -31
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuwait.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Magadan.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Muscat.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Novosibirsk.rb +0 -164
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Rangoon.rb +0 -24
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Riyadh.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Seoul.rb +0 -34
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Shanghai.rb +0 -35
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Singapore.rb +0 -33
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Taipei.rb +0 -59
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tashkent.rb +0 -47
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tbilisi.rb +0 -78
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tehran.rb +0 -121
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tokyo.rb +0 -30
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Ulaanbaatar.rb +0 -65
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Urumqi.rb +0 -33
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Vladivostok.rb +0 -164
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yakutsk.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yekaterinburg.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yerevan.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Azores.rb +0 -270
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Cape_Verde.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/South_Georgia.rb +0 -18
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Adelaide.rb +0 -187
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Brisbane.rb +0 -35
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Darwin.rb +0 -29
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Hobart.rb +0 -193
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Melbourne.rb +0 -185
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Perth.rb +0 -37
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Sydney.rb +0 -185
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Etc/UTC.rb +0 -16
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Amsterdam.rb +0 -228
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Athens.rb +0 -185
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Belgrade.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Berlin.rb +0 -188
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bratislava.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Brussels.rb +0 -232
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bucharest.rb +0 -181
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Budapest.rb +0 -197
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Copenhagen.rb +0 -179
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Dublin.rb +0 -276
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Helsinki.rb +0 -163
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Istanbul.rb +0 -218
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Kiev.rb +0 -168
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Lisbon.rb +0 -268
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Ljubljana.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/London.rb +0 -288
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Madrid.rb +0 -211
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Minsk.rb +0 -170
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Moscow.rb +0 -181
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Paris.rb +0 -232
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Prague.rb +0 -187
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Riga.rb +0 -176
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Rome.rb +0 -215
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sarajevo.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Skopje.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sofia.rb +0 -173
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Stockholm.rb +0 -165
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Tallinn.rb +0 -172
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vienna.rb +0 -183
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vilnius.rb +0 -170
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Warsaw.rb +0 -212
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Zagreb.rb +0 -13
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Auckland.rb +0 -202
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Fiji.rb +0 -23
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Guam.rb +0 -22
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Honolulu.rb +0 -28
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Majuro.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Midway.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Noumea.rb +0 -25
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Pago_Pago.rb +0 -26
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Port_Moresby.rb +0 -20
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Tongatapu.rb +0 -27
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/info_timezone.rb +0 -52
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone.rb +0 -51
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone_info.rb +0 -44
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/offset_rationals.rb +0 -98
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/ruby_core_support.rb +0 -56
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/time_or_datetime.rb +0 -292
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone.rb +0 -508
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_definition.rb +0 -56
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_info.rb +0 -40
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_offset_info.rb +0 -94
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_period.rb +0 -198
- data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_transition_info.rb +0 -129
data/CHANGELOG
CHANGED
@@ -1,4 +1,124 @@
|
|
1
|
-
*
|
1
|
+
*Rails 3.0.0 [release candidate] (July 26th, 2010)*
|
2
|
+
|
3
|
+
* Removed Object#returning, Object#tap should be used instead. [Santiago Pastorino]
|
4
|
+
|
5
|
+
* Deprecation behavior is no longer hardcoded to the name of the environment.
|
6
|
+
Instead, it is set via config.active_support.deprecation and can be one
|
7
|
+
of :log, :stderr or :notify. :notify is a new style that sends the warning
|
8
|
+
via ActiveSupport::Notifications, and is the new default for production
|
9
|
+
[Yehuda Katz]
|
10
|
+
|
11
|
+
* Renamed ActiveSupport::Dependecies.load_(once_)paths to autoload_(once_)paths. [fxn]
|
12
|
+
|
13
|
+
* Added ActiveSupport::FileUpdateChecker to execute a block only if a set of files changed, used by Router and I18n locale files. [José Valim]
|
14
|
+
|
15
|
+
* Added ActiveSupport::DescendantsTracker to track descendants with support to constants reloading. [José Valim]
|
16
|
+
|
17
|
+
* ActiveSupport::OrderedHash#merge and #merge! accept a block. #4838 [Paul Mucur, fxn]
|
18
|
+
|
19
|
+
* Date#since, #ago, #beginning_of_day, #end_of_day, and #xmlschema honor now the user time zone if set. [Geoff Buesing]
|
20
|
+
|
21
|
+
|
22
|
+
*Rails 3.0.0 [beta 4] (June 8th, 2010)*
|
23
|
+
|
24
|
+
* Extracted String#truncate from TextHelper#truncate [DHH]
|
25
|
+
|
26
|
+
* Ruby 1.9: support UTF-8 case folding. #4595 [Norman Clarke]
|
27
|
+
|
28
|
+
* Removes Array#rand and backports Array#sample from Ruby 1.9, thanks to Marc-Andre Lafortune. [fxn]
|
29
|
+
|
30
|
+
* Ruby 1.9: Renames last_(month|year) to prev_(month|year) in Date and Time. [fxn]
|
31
|
+
|
32
|
+
* Aliases Date#sunday to Date#end_of_week. [fxn]
|
33
|
+
|
34
|
+
* Backports Date#>> from 1.9 so that calculations do the right thing around the calendar reform. [fxn]
|
35
|
+
|
36
|
+
* Date#to_time handles properly years in the range 0..138. [fxn]
|
37
|
+
|
38
|
+
* Deprecate {{}} as interpolation syntax for I18n in favor of %{} [José Valim]
|
39
|
+
|
40
|
+
* Array#to_xml is more powerful and able to handle the same types as Hash#to_xml #4490 [Neeraj Singh]
|
41
|
+
|
42
|
+
* Harmonize the caching API and refactor the backends. #4452 [Brian Durand]
|
43
|
+
All caches:
|
44
|
+
* Add default options to initializer that will be sent to all read, write, fetch, exist?, increment, and decrement
|
45
|
+
* Add support for the :expires_in option to fetch and write for all caches. Cache entries are stored with the create timestamp and a ttl so that expiration can be handled independently of the implementation.
|
46
|
+
* Add support for a :namespace option. This can be used to set a global prefix for cache entries.
|
47
|
+
* Deprecate expand_cache_key on ActiveSupport::Cache and move it to ActionController::Caching and ActionDispatch::Http::Cache since the logic in the method used some Rails specific environment variables and was only used by ActionPack classes. Not very DRY but there didn't seem to be a good shared spot and ActiveSupport really shouldn't be Rails specific.
|
48
|
+
* Add support for :race_condition_ttl to fetch. This setting can prevent race conditions on fetch calls where several processes try to regenerate a recently expired entry at once.
|
49
|
+
* Add support for :compress option to fetch and write which will compress any data over a configurable threshold.
|
50
|
+
* Nil values can now be stored in the cache and are distinct from cache misses for fetch.
|
51
|
+
* Easier API to create new implementations. Just need to implement the methods read_entry, write_entry, and delete_entry instead of overwriting existing methods.
|
52
|
+
* Since all cache implementations support storing objects, update the docs to state that ActiveCache::Cache::Store implementations should store objects. Keys, however, must be strings since some implementations require that.
|
53
|
+
* Increase test coverage.
|
54
|
+
* Document methods which are provided as convenience but which may not be universally available.
|
55
|
+
|
56
|
+
MemoryStore:
|
57
|
+
* MemoryStore can now safely be used as the cache for single server sites.
|
58
|
+
* Make thread safe so that the default cache implementation used by Rails is thread safe. The overhead is minimal and it is still the fastest store available.
|
59
|
+
* Provide :size initialization option indicating the maximum size of the cache in memory (defaults to 32Mb).
|
60
|
+
* Add prune logic that removes the least recently used cache entries to keep the cache size from exceeding the max.
|
61
|
+
* Deprecated SynchronizedMemoryStore since it isn't needed anymore.
|
62
|
+
|
63
|
+
FileStore:
|
64
|
+
* Escape key values so they will work as file names on all file systems, be consistent, and case sensitive
|
65
|
+
* Use a hash algorithm to segment the cache into sub directories so that a large cache doesn't exceed file system limits.
|
66
|
+
* FileStore can be slow so implement the LocalCache strategy to cache reads for the duration of a request.
|
67
|
+
* Add cleanup method to keep the disk from filling up with expired entries.
|
68
|
+
* Fix increment and decrement to use file system locks so they are consistent between processes.
|
69
|
+
|
70
|
+
MemCacheStore:
|
71
|
+
* Support all keys. Previously keys with spaces in them would fail
|
72
|
+
* Deprecate CompressedMemCacheStore since it isn't needed anymore (use :compress => true)
|
73
|
+
|
74
|
+
* JSON: encode objects that don't have a native JSON representation using to_hash, if available, instead of instance_values (the old fallback) or to_s (other encoders' default). Encode BigDecimal and Regexp encode as strings to conform with other encoders. Try to transcode non-UTF-8 strings. [Jeremy Kemper]
|
75
|
+
|
76
|
+
|
77
|
+
*Rails 3.0.0 [beta 3] (April 13th, 2010)*
|
78
|
+
|
79
|
+
* HashWithIndifferentAccess: remove inherited symbolize_keys! since its keys are always strings. [Santiago Pastorino]
|
80
|
+
|
81
|
+
* Improve transliteration quality. #4374 [Norman Clarke]
|
82
|
+
|
83
|
+
* Speed up and add Ruby 1.9 support for ActiveSupport::Multibyte::Chars#tidy_bytes. #4350 [Norman Clarke]
|
84
|
+
|
85
|
+
|
86
|
+
*Rails 3.0.0 [beta 2] (April 1st, 2010)*
|
87
|
+
|
88
|
+
* Reduced load time by deferring configuration of classes using
|
89
|
+
ActiveSupport::on_load(:component_name) [YK]
|
90
|
+
|
91
|
+
* Rename #metaclass to #singleton_class now that ruby-core has decided [JK]
|
92
|
+
|
93
|
+
* New assertions assert_blank and assert_present. #4299 [Juanjo Bazan]
|
94
|
+
|
95
|
+
* Use Object#singleton_class instead of #metaclass. Prefer Ruby's choice. [Jeremy Kemper]
|
96
|
+
|
97
|
+
* JSON backend for YAJL. Preferred if available. #2666 [Brian Lopez]
|
98
|
+
|
99
|
+
|
100
|
+
*Rails 3.0.0 [beta 1] (February 4, 2010)*
|
101
|
+
|
102
|
+
* Introduce class_attribute to declare inheritable class attributes. Writing an attribute on a subclass behaves just like overriding the superclass reader method. Unifies and replaces most usage of cattr_accessor, class_inheritable_attribute, superclass_delegating_attribute, and extlib_inheritable_attribute. [Jeremy Kemper, Yehuda Katz]
|
103
|
+
|
104
|
+
* Time#- with a DateTime argument behaves the same as with a Time argument, i.e. returns the difference between self and arg as a Float #3476 [Geoff Buesing]
|
105
|
+
|
106
|
+
* YAML serialization for OrderedHash. #3608 [Gregor Schmidt]
|
107
|
+
|
108
|
+
* Update bundled TZInfo to v0.3.16 [Geoff Buesing]
|
109
|
+
|
110
|
+
* Georgetown TimeZone is now mapped to "America/Guyana" instead of "America/Argentina/San_Juan" #1821 [Geoff Buesing, Reuben Sivan]
|
111
|
+
|
112
|
+
* Changed the default ActiveSupport.use_standard_json_time_format from false to true and
|
113
|
+
ActiveSupport.escape_html_entities_in_json from true to false to match previously announced Rails 3 defaults [DHH]
|
114
|
+
|
115
|
+
* Added Object#presence that returns the object if it's #present? otherwise returns nil [DHH/Colin Kelley]
|
116
|
+
|
117
|
+
* Add Enumerable#exclude? to bring parity to Enumerable#include? and avoid if !x.include?/else calls [DHH]
|
118
|
+
|
119
|
+
* Update Edinburgh TimeZone to use "Europe/London" instead of "Europe/Dublin" #3310 [Phil Ross]
|
120
|
+
|
121
|
+
* Update bundled TZInfo to v0.3.15 [Geoff Buesing]
|
2
122
|
|
3
123
|
* JSON: +Object#to_json+ calls +as_json+ to coerce itself into something natively encodable like +Hash+, +Integer+, or +String+. Override +as_json+ instead of +to_json+ so you're JSON library agnostic. [Jeremy Kemper]
|
4
124
|
|
data/README.rdoc
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
= Active Support -- Utility classes and Ruby extensions from Rails
|
2
|
+
|
3
|
+
Active Support is a collection of utility classes and standard library
|
4
|
+
extensions that were found useful for the Rails framework. These additions
|
5
|
+
reside in this package so they can be loaded as needed in Ruby projects
|
6
|
+
outside of Rails.
|
7
|
+
|
8
|
+
|
9
|
+
== Download and installation
|
10
|
+
|
11
|
+
The latest version of Active Support can be installed with Rubygems:
|
12
|
+
|
13
|
+
% [sudo] gem install activesupport
|
14
|
+
|
15
|
+
Source code can be downloaded as part of the Rails project on GitHub
|
16
|
+
|
17
|
+
* http://github.com/rails/rails/tree/master/activesupport/
|
18
|
+
|
19
|
+
|
20
|
+
== License
|
21
|
+
|
22
|
+
Active Support is released under the MIT license.
|
23
|
+
|
24
|
+
|
25
|
+
== Support
|
26
|
+
|
27
|
+
API documentation is at
|
28
|
+
|
29
|
+
* http://api.rubyonrails.com
|
30
|
+
|
31
|
+
Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
|
32
|
+
|
33
|
+
* https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets
|
data/lib/active_support.rb
CHANGED
@@ -34,8 +34,46 @@ module ActiveSupport
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
require
|
38
|
-
require 'active_support/vendor'
|
37
|
+
require "active_support/dependencies/autoload"
|
39
38
|
|
40
|
-
|
41
|
-
|
39
|
+
module ActiveSupport
|
40
|
+
extend ActiveSupport::Autoload
|
41
|
+
|
42
|
+
autoload :DescendantsTracker
|
43
|
+
autoload :FileUpdateChecker
|
44
|
+
autoload :LogSubscriber
|
45
|
+
autoload :Notifications
|
46
|
+
|
47
|
+
# TODO: Narrow this list down
|
48
|
+
eager_autoload do
|
49
|
+
autoload :BacktraceCleaner
|
50
|
+
autoload :Base64
|
51
|
+
autoload :BasicObject
|
52
|
+
autoload :Benchmarkable
|
53
|
+
autoload :BufferedLogger
|
54
|
+
autoload :Cache
|
55
|
+
autoload :Callbacks
|
56
|
+
autoload :Concern
|
57
|
+
autoload :Configurable
|
58
|
+
autoload :Deprecation
|
59
|
+
autoload :Gzip
|
60
|
+
autoload :Inflector
|
61
|
+
autoload :JSON
|
62
|
+
autoload :Memoizable
|
63
|
+
autoload :MessageEncryptor
|
64
|
+
autoload :MessageVerifier
|
65
|
+
autoload :Multibyte
|
66
|
+
autoload :OptionMerger
|
67
|
+
autoload :OrderedHash
|
68
|
+
autoload :OrderedOptions
|
69
|
+
autoload :Rescuable
|
70
|
+
autoload :SecureRandom
|
71
|
+
autoload :StringInquirer
|
72
|
+
autoload :XmlMini
|
73
|
+
end
|
74
|
+
|
75
|
+
autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
|
76
|
+
autoload :TestCase
|
77
|
+
end
|
78
|
+
|
79
|
+
autoload :I18n, "active_support/i18n"
|
@@ -4,12 +4,14 @@ module ActiveSupport
|
|
4
4
|
# context, so only the relevant lines are included.
|
5
5
|
#
|
6
6
|
# If you need to reconfigure an existing BacktraceCleaner, like the one in Rails, to show as much as possible, you can always
|
7
|
-
# call BacktraceCleaner#remove_silencers!
|
7
|
+
# call BacktraceCleaner#remove_silencers! Also, if you need to reconfigure an existing BacktraceCleaner so that it does not
|
8
|
+
# filter or modify the paths of any lines of the backtrace, you can call BacktraceCleaner#remove_filters! These two methods
|
9
|
+
# will give you a completely untouched backtrace.
|
8
10
|
#
|
9
11
|
# Example:
|
10
12
|
#
|
11
13
|
# bc = BacktraceCleaner.new
|
12
|
-
# bc.add_filter { |line| line.gsub(Rails.root, '') }
|
14
|
+
# bc.add_filter { |line| line.gsub(Rails.root, '') }
|
13
15
|
# bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
|
14
16
|
# bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
|
15
17
|
#
|
@@ -18,10 +20,19 @@ module ActiveSupport
|
|
18
20
|
def initialize
|
19
21
|
@filters, @silencers = [], []
|
20
22
|
end
|
21
|
-
|
23
|
+
|
22
24
|
# Returns the backtrace after all filters and silencers has been run against it. Filters run first, then silencers.
|
23
|
-
def clean(backtrace)
|
24
|
-
|
25
|
+
def clean(backtrace, kind = :silent)
|
26
|
+
filtered = filter(backtrace)
|
27
|
+
|
28
|
+
case kind
|
29
|
+
when :silent
|
30
|
+
silence(filtered)
|
31
|
+
when :noise
|
32
|
+
noise(filtered)
|
33
|
+
else
|
34
|
+
filtered
|
35
|
+
end
|
25
36
|
end
|
26
37
|
|
27
38
|
# Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.
|
@@ -51,21 +62,32 @@ module ActiveSupport
|
|
51
62
|
@silencers = []
|
52
63
|
end
|
53
64
|
|
54
|
-
|
65
|
+
def remove_filters!
|
66
|
+
@filters = []
|
67
|
+
end
|
68
|
+
|
55
69
|
private
|
56
70
|
def filter(backtrace)
|
57
71
|
@filters.each do |f|
|
58
72
|
backtrace = backtrace.map { |line| f.call(line) }
|
59
73
|
end
|
60
|
-
|
74
|
+
|
61
75
|
backtrace
|
62
76
|
end
|
63
|
-
|
77
|
+
|
64
78
|
def silence(backtrace)
|
65
79
|
@silencers.each do |s|
|
66
80
|
backtrace = backtrace.reject { |line| s.call(line) }
|
67
81
|
end
|
68
|
-
|
82
|
+
|
83
|
+
backtrace
|
84
|
+
end
|
85
|
+
|
86
|
+
def noise(backtrace)
|
87
|
+
@silencers.each do |s|
|
88
|
+
backtrace = backtrace.select { |line| s.call(line) }
|
89
|
+
end
|
90
|
+
|
69
91
|
backtrace
|
70
92
|
end
|
71
93
|
end
|
@@ -53,7 +53,6 @@ module ActiveSupport
|
|
53
53
|
FileUtils.mkdir_p(File.dirname(log))
|
54
54
|
@log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
|
55
55
|
@log.sync = true
|
56
|
-
@log.write("# Logfile created on %s" % [Time.now.to_s])
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
@@ -102,7 +101,11 @@ module ActiveSupport
|
|
102
101
|
@guard.synchronize do
|
103
102
|
unless buffer.empty?
|
104
103
|
old_buffer = buffer
|
105
|
-
|
104
|
+
all_content = StringIO.new
|
105
|
+
old_buffer.each do |content|
|
106
|
+
all_content << content
|
107
|
+
end
|
108
|
+
@log.write(all_content.string)
|
106
109
|
end
|
107
110
|
|
108
111
|
# Important to do this even if buffer was empty or else @buffer will
|
data/lib/active_support/cache.rb
CHANGED
@@ -1,23 +1,30 @@
|
|
1
1
|
require 'benchmark'
|
2
|
+
require 'zlib'
|
3
|
+
require 'active_support/core_ext/array/extract_options'
|
4
|
+
require 'active_support/core_ext/array/wrap'
|
2
5
|
require 'active_support/core_ext/benchmark'
|
3
6
|
require 'active_support/core_ext/exception'
|
4
7
|
require 'active_support/core_ext/class/attribute_accessors'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
# require 'active_support/core_ext' # FIXME: pulling in all to_param extensions
|
8
|
+
require 'active_support/core_ext/numeric/bytes'
|
9
|
+
require 'active_support/core_ext/numeric/time'
|
10
|
+
require 'active_support/core_ext/object/to_param'
|
11
|
+
require 'active_support/core_ext/string/inflections'
|
11
12
|
|
12
13
|
module ActiveSupport
|
13
14
|
# See ActiveSupport::Cache::Store for documentation.
|
14
15
|
module Cache
|
15
16
|
autoload :FileStore, 'active_support/cache/file_store'
|
16
17
|
autoload :MemoryStore, 'active_support/cache/memory_store'
|
17
|
-
autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store'
|
18
18
|
autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
|
19
|
+
autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store'
|
19
20
|
autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store'
|
20
21
|
|
22
|
+
EMPTY_OPTIONS = {}.freeze
|
23
|
+
|
24
|
+
# These options mean something to all cache implementations. Individual cache
|
25
|
+
# implementations may support additional options.
|
26
|
+
UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
|
27
|
+
|
21
28
|
module Strategy
|
22
29
|
autoload :LocalCache, 'active_support/cache/strategy/local_cache'
|
23
30
|
end
|
@@ -33,7 +40,7 @@ module ActiveSupport
|
|
33
40
|
#
|
34
41
|
# ActiveSupport::Cache.lookup_store(:memory_store)
|
35
42
|
# # => returns a new ActiveSupport::Cache::MemoryStore object
|
36
|
-
#
|
43
|
+
#
|
37
44
|
# ActiveSupport::Cache.lookup_store(:mem_cache_store)
|
38
45
|
# # => returns a new ActiveSupport::Cache::MemCacheStore object
|
39
46
|
#
|
@@ -48,7 +55,7 @@ module ActiveSupport
|
|
48
55
|
# ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
|
49
56
|
# # => returns MyOwnCacheStore.new
|
50
57
|
def self.lookup_store(*store_option)
|
51
|
-
store, *parameters = *(
|
58
|
+
store, *parameters = *Array.wrap(store_option).flatten
|
52
59
|
|
53
60
|
case store
|
54
61
|
when Symbol
|
@@ -62,15 +69,12 @@ module ActiveSupport
|
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
65
|
-
RAILS_CACHE_ID = ENV["RAILS_CACHE_ID"]
|
66
|
-
RAILS_APP_VERION = ENV["RAILS_APP_VERION"]
|
67
|
-
EXPANDED_CACHE = RAILS_CACHE_ID || RAILS_APP_VERION
|
68
|
-
|
69
72
|
def self.expand_cache_key(key, namespace = nil)
|
70
73
|
expanded_cache_key = namespace ? "#{namespace}/" : ""
|
71
74
|
|
72
|
-
|
73
|
-
|
75
|
+
prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
|
76
|
+
if prefix
|
77
|
+
expanded_cache_key << "#{prefix}/"
|
74
78
|
end
|
75
79
|
|
76
80
|
expanded_cache_key <<
|
@@ -95,26 +99,75 @@ module ActiveSupport
|
|
95
99
|
# ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most
|
96
100
|
# popular cache store for large production websites.
|
97
101
|
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
102
|
+
# Some implementations may not support all methods beyond the basic cache
|
103
|
+
# methods of +fetch+, +write+, +read+, +exist?+, and +delete+.
|
104
|
+
#
|
105
|
+
# ActiveSupport::Cache::Store can store any serializable Ruby object.
|
101
106
|
#
|
102
107
|
# cache = ActiveSupport::Cache::MemoryStore.new
|
103
|
-
#
|
108
|
+
#
|
104
109
|
# cache.read("city") # => nil
|
105
110
|
# cache.write("city", "Duckburgh")
|
106
111
|
# cache.read("city") # => "Duckburgh"
|
112
|
+
#
|
113
|
+
# Keys are always translated into Strings and are case sensitive. When an
|
114
|
+
# object is specified as a key, its +cache_key+ method will be called if it
|
115
|
+
# is defined. Otherwise, the +to_param+ method will be called. Hashes and
|
116
|
+
# Arrays can be used as keys. The elements will be delimited by slashes
|
117
|
+
# and Hashes elements will be sorted by key so they are consistent.
|
118
|
+
#
|
119
|
+
# cache.read("city") == cache.read(:city) # => true
|
120
|
+
#
|
121
|
+
# Nil values can be cached.
|
122
|
+
#
|
123
|
+
# If your cache is on a shared infrastructure, you can define a namespace for
|
124
|
+
# your cache entries. If a namespace is defined, it will be prefixed on to every
|
125
|
+
# key. The namespace can be either a static value or a Proc. If it is a Proc, it
|
126
|
+
# will be invoked when each key is evaluated so that you can use application logic
|
127
|
+
# to invalidate keys.
|
128
|
+
#
|
129
|
+
# cache.namespace = lambda { @last_mod_time } # Set the namespace to a variable
|
130
|
+
# @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
|
131
|
+
#
|
132
|
+
# All caches support auto expiring content after a specified number of seconds.
|
133
|
+
# To set the cache entry time to live, you can either specify +:expires_in+ as
|
134
|
+
# an option to the constructor to have it affect all entries or to the +fetch+
|
135
|
+
# or +write+ methods for just one entry.
|
136
|
+
#
|
137
|
+
# cache = ActiveSupport::Cache::MemoryStore.new(:expire_in => 5.minutes)
|
138
|
+
# cache.write(key, value, :expire_in => 1.minute) # Set a lower value for one entry
|
139
|
+
#
|
140
|
+
# Caches can also store values in a compressed format to save space and reduce
|
141
|
+
# time spent sending data. Since there is some overhead, values must be large
|
142
|
+
# enough to warrant compression. To turn on compression either pass
|
143
|
+
# <tt>:compress => true</tt> in the initializer or to +fetch+ or +write+.
|
144
|
+
# To specify the threshold at which to compress values, set
|
145
|
+
# <tt>:compress_threshold</tt>. The default threshold is 32K.
|
107
146
|
class Store
|
108
|
-
|
147
|
+
|
148
|
+
cattr_accessor :logger, :instance_writer => true
|
109
149
|
|
110
150
|
attr_reader :silence
|
111
151
|
alias :silence? :silence
|
112
152
|
|
153
|
+
# Create a new cache. The options will be passed to any write method calls except
|
154
|
+
# for :namespace which can be used to set the global namespace for the cache.
|
155
|
+
def initialize (options = nil)
|
156
|
+
@options = options ? options.dup : {}
|
157
|
+
end
|
158
|
+
|
159
|
+
# Get the default options set when the cache was created.
|
160
|
+
def options
|
161
|
+
@options ||= {}
|
162
|
+
end
|
163
|
+
|
164
|
+
# Silence the logger.
|
113
165
|
def silence!
|
114
166
|
@silence = true
|
115
167
|
self
|
116
168
|
end
|
117
169
|
|
170
|
+
# Silence the logger within a block.
|
118
171
|
def mute
|
119
172
|
previous_silence, @silence = defined?(@silence) && @silence, true
|
120
173
|
yield
|
@@ -142,7 +195,7 @@ module ActiveSupport
|
|
142
195
|
#
|
143
196
|
# cache.write("today", "Monday")
|
144
197
|
# cache.fetch("today") # => "Monday"
|
145
|
-
#
|
198
|
+
#
|
146
199
|
# cache.fetch("city") # => nil
|
147
200
|
# cache.fetch("city") do
|
148
201
|
# "Duckburgh"
|
@@ -155,29 +208,98 @@ module ActiveSupport
|
|
155
208
|
# cache.write("today", "Monday")
|
156
209
|
# cache.fetch("today", :force => true) # => nil
|
157
210
|
#
|
211
|
+
# Setting <tt>:compress</tt> will store a large cache entry set by the call
|
212
|
+
# in a compressed format.
|
213
|
+
#
|
214
|
+
# Setting <tt>:expires_in</tt> will set an expiration time on the cache
|
215
|
+
# entry if it is set by call.
|
216
|
+
#
|
217
|
+
# Setting <tt>:race_condition_ttl</tt> will invoke logic on entries set with
|
218
|
+
# an <tt>:expires_in</tt> option. If an entry is found in the cache that is
|
219
|
+
# expired and it has been expired for less than the number of seconds specified
|
220
|
+
# by this option and a block was passed to the method call, then the expiration
|
221
|
+
# future time of the entry in the cache will be updated to that many seconds
|
222
|
+
# in the and the block will be evaluated and written to the cache.
|
223
|
+
#
|
224
|
+
# This is very useful in situations where a cache entry is used very frequently
|
225
|
+
# under heavy load. The first process to find an expired cache entry will then
|
226
|
+
# become responsible for regenerating that entry while other processes continue
|
227
|
+
# to use the slightly out of date entry. This can prevent race conditions where
|
228
|
+
# too many processes are trying to regenerate the entry all at once. If the
|
229
|
+
# process regenerating the entry errors out, the entry will be regenerated
|
230
|
+
# after the specified number of seconds.
|
231
|
+
#
|
232
|
+
# # Set all values to expire after one minute.
|
233
|
+
# cache = ActiveSupport::Cache::MemoryCache.new(:expires_in => 1.minute)
|
234
|
+
#
|
235
|
+
# cache.write("foo", "original value")
|
236
|
+
# val_1 = nil
|
237
|
+
# val_2 = nil
|
238
|
+
# sleep 60
|
239
|
+
#
|
240
|
+
# Thread.new do
|
241
|
+
# val_1 = cache.fetch("foo", :race_condition_ttl => 10) do
|
242
|
+
# sleep 1
|
243
|
+
# "new value 1"
|
244
|
+
# end
|
245
|
+
# end
|
246
|
+
#
|
247
|
+
# Thread.new do
|
248
|
+
# val_2 = cache.fetch("foo", :race_condition_ttl => 10) do
|
249
|
+
# "new value 2"
|
250
|
+
# end
|
251
|
+
# end
|
252
|
+
#
|
253
|
+
# # val_1 => "new value 1"
|
254
|
+
# # val_2 => "original value"
|
255
|
+
# # cache.fetch("foo") => "new value 1"
|
256
|
+
#
|
158
257
|
# Other options will be handled by the specific cache store implementation.
|
159
|
-
# Internally, #fetch calls #
|
258
|
+
# Internally, #fetch calls #read_entry, and calls #write_entry on a cache miss.
|
160
259
|
# +options+ will be passed to the #read and #write calls.
|
161
260
|
#
|
162
|
-
# For example, MemCacheStore's #write method supports the +:
|
163
|
-
# option, which tells the memcached server to
|
164
|
-
#
|
165
|
-
# FileStore's #read method. We can use this option with #fetch too:
|
261
|
+
# For example, MemCacheStore's #write method supports the +:raw+
|
262
|
+
# option, which tells the memcached server to store all values as strings.
|
263
|
+
# We can use this option with #fetch too:
|
166
264
|
#
|
167
265
|
# cache = ActiveSupport::Cache::MemCacheStore.new
|
168
|
-
# cache.fetch("foo", :force => true, :
|
169
|
-
#
|
266
|
+
# cache.fetch("foo", :force => true, :raw => true) do
|
267
|
+
# :bar
|
170
268
|
# end
|
171
269
|
# cache.fetch("foo") # => "bar"
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
270
|
+
def fetch(name, options = nil)
|
271
|
+
if block_given?
|
272
|
+
options = merged_options(options)
|
273
|
+
key = namespaced_key(name, options)
|
274
|
+
unless options[:force]
|
275
|
+
entry = instrument(:read, name, options) do |payload|
|
276
|
+
payload[:super_operation] = :fetch if payload
|
277
|
+
read_entry(key, options)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
if entry && entry.expired?
|
281
|
+
race_ttl = options[:race_condition_ttl].to_f
|
282
|
+
if race_ttl and Time.now.to_f - entry.expires_at <= race_ttl
|
283
|
+
entry.expires_at = Time.now + race_ttl
|
284
|
+
write_entry(key, entry, :expires_in => race_ttl * 2)
|
285
|
+
else
|
286
|
+
delete_entry(key, options)
|
287
|
+
end
|
288
|
+
entry = nil
|
289
|
+
end
|
290
|
+
|
291
|
+
if entry
|
292
|
+
instrument(:fetch_hit, name, options) { |payload| }
|
293
|
+
entry.value
|
294
|
+
else
|
295
|
+
result = instrument(:generate, name, options) do |payload|
|
296
|
+
yield
|
297
|
+
end
|
298
|
+
write(name, result, options)
|
299
|
+
result
|
300
|
+
end
|
301
|
+
else
|
302
|
+
read(name, options)
|
181
303
|
end
|
182
304
|
end
|
183
305
|
|
@@ -185,15 +307,50 @@ module ActiveSupport
|
|
185
307
|
# the cache with the given key, then that data is returned. Otherwise,
|
186
308
|
# nil is returned.
|
187
309
|
#
|
188
|
-
#
|
189
|
-
|
190
|
-
|
310
|
+
# Options are passed to the underlying cache implementation.
|
311
|
+
def read(name, options = nil)
|
312
|
+
options = merged_options(options)
|
313
|
+
key = namespaced_key(name, options)
|
314
|
+
instrument(:read, name, options) do |payload|
|
315
|
+
entry = read_entry(key, options)
|
316
|
+
if entry
|
317
|
+
if entry.expired?
|
318
|
+
delete_entry(key, options)
|
319
|
+
payload[:hit] = false if payload
|
320
|
+
nil
|
321
|
+
else
|
322
|
+
payload[:hit] = true if payload
|
323
|
+
entry.value
|
324
|
+
end
|
325
|
+
else
|
326
|
+
payload[:hit] = false if payload
|
327
|
+
nil
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
# Read multiple values at once from the cache. Options can be passed
|
333
|
+
# in the last argument.
|
334
|
+
#
|
335
|
+
# Some cache implementation may optimize this method.
|
191
336
|
#
|
192
|
-
#
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
337
|
+
# Returns a hash mapping the names provided to the values found.
|
338
|
+
def read_multi(*names)
|
339
|
+
options = names.extract_options!
|
340
|
+
options = merged_options(options)
|
341
|
+
results = {}
|
342
|
+
names.each do |name|
|
343
|
+
key = namespaced_key(name, options)
|
344
|
+
entry = read_entry(key, options)
|
345
|
+
if entry
|
346
|
+
if entry.expired?
|
347
|
+
delete_entry(key)
|
348
|
+
else
|
349
|
+
results[name] = entry.value
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
results
|
197
354
|
end
|
198
355
|
|
199
356
|
# Writes the given value to the cache, with the given key.
|
@@ -201,70 +358,283 @@ module ActiveSupport
|
|
201
358
|
# You may also specify additional options via the +options+ argument.
|
202
359
|
# The specific cache store implementation will decide what to do with
|
203
360
|
# +options+.
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
361
|
+
def write(name, value, options = nil)
|
362
|
+
options = merged_options(options)
|
363
|
+
instrument(:write, name, options) do |payload|
|
364
|
+
entry = Entry.new(value, options)
|
365
|
+
write_entry(namespaced_key(name, options), entry, options)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
# Delete an entry in the cache. Returns +true+ if there was an entry to delete.
|
208
370
|
#
|
209
|
-
#
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
instrument(:write, key, options, &block)
|
371
|
+
# Options are passed to the underlying cache implementation.
|
372
|
+
def delete(name, options = nil)
|
373
|
+
options = merged_options(options)
|
374
|
+
instrument(:delete, name) do |payload|
|
375
|
+
delete_entry(namespaced_key(name, options), options)
|
376
|
+
end
|
216
377
|
end
|
217
378
|
|
218
|
-
|
219
|
-
|
379
|
+
# Return true if the cache contains an entry with this name.
|
380
|
+
#
|
381
|
+
# Options are passed to the underlying cache implementation.
|
382
|
+
def exist?(name, options = nil)
|
383
|
+
options = merged_options(options)
|
384
|
+
instrument(:exist?, name) do |payload|
|
385
|
+
entry = read_entry(namespaced_key(name, options), options)
|
386
|
+
if entry && !entry.expired?
|
387
|
+
true
|
388
|
+
else
|
389
|
+
false
|
390
|
+
end
|
391
|
+
end
|
220
392
|
end
|
221
393
|
|
222
|
-
|
223
|
-
|
394
|
+
# Delete all entries whose keys match a pattern.
|
395
|
+
#
|
396
|
+
# Options are passed to the underlying cache implementation.
|
397
|
+
#
|
398
|
+
# Not all implementations may support +delete_matched+.
|
399
|
+
def delete_matched(matcher, options = nil)
|
400
|
+
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
|
224
401
|
end
|
225
402
|
|
226
|
-
|
227
|
-
|
403
|
+
# Increment an integer value in the cache.
|
404
|
+
#
|
405
|
+
# Options are passed to the underlying cache implementation.
|
406
|
+
#
|
407
|
+
# Not all implementations may support +delete_matched+.
|
408
|
+
def increment(name, amount = 1, options = nil)
|
409
|
+
raise NotImplementedError.new("#{self.class.name} does not support increment")
|
228
410
|
end
|
229
411
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
412
|
+
# Increment an integer value in the cache.
|
413
|
+
#
|
414
|
+
# Options are passed to the underlying cache implementation.
|
415
|
+
#
|
416
|
+
# Not all implementations may support +delete_matched+.
|
417
|
+
def decrement(name, amount = 1, options = nil)
|
418
|
+
raise NotImplementedError.new("#{self.class.name} does not support decrement")
|
236
419
|
end
|
237
420
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
421
|
+
# Cleanup the cache by removing expired entries. Not all cache implementations may
|
422
|
+
# support this method.
|
423
|
+
#
|
424
|
+
# Options are passed to the underlying cache implementation.
|
425
|
+
#
|
426
|
+
# Not all implementations may support +delete_matched+.
|
427
|
+
def cleanup(options = nil)
|
428
|
+
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
|
244
429
|
end
|
245
430
|
|
431
|
+
# Clear the entire cache. Not all cache implementations may support this method.
|
432
|
+
# You should be careful with this method since it could affect other processes
|
433
|
+
# if you are using a shared cache.
|
434
|
+
#
|
435
|
+
# Options are passed to the underlying cache implementation.
|
436
|
+
#
|
437
|
+
# Not all implementations may support +delete_matched+.
|
438
|
+
def clear(options = nil)
|
439
|
+
raise NotImplementedError.new("#{self.class.name} does not support clear")
|
440
|
+
end
|
441
|
+
|
442
|
+
protected
|
443
|
+
# Add the namespace defined in the options to a pattern designed to match keys.
|
444
|
+
# Implementations that support delete_matched should call this method to translate
|
445
|
+
# a pattern that matches names into one that matches namespaced keys.
|
446
|
+
def key_matcher(pattern, options)
|
447
|
+
prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
|
448
|
+
if prefix
|
449
|
+
source = pattern.source
|
450
|
+
if source.start_with?('^')
|
451
|
+
source = source[1, source.length]
|
452
|
+
else
|
453
|
+
source = ".*#{source[0, source.length]}"
|
454
|
+
end
|
455
|
+
Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options)
|
456
|
+
else
|
457
|
+
pattern
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
# Read an entry from the cache implementation. Subclasses must implement this method.
|
462
|
+
def read_entry(key, options) # :nodoc:
|
463
|
+
raise NotImplementedError.new
|
464
|
+
end
|
465
|
+
|
466
|
+
# Write an entry to the cache implementation. Subclasses must implement this method.
|
467
|
+
def write_entry(key, entry, options) # :nodoc:
|
468
|
+
raise NotImplementedError.new
|
469
|
+
end
|
470
|
+
|
471
|
+
# Delete an entry from the cache implementation. Subclasses must implement this method.
|
472
|
+
def delete_entry(key, options) # :nodoc:
|
473
|
+
raise NotImplementedError.new
|
474
|
+
end
|
475
|
+
|
246
476
|
private
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
477
|
+
# Merge the default options with ones specific to a method call.
|
478
|
+
def merged_options(call_options) # :nodoc:
|
479
|
+
if call_options
|
480
|
+
options.merge(call_options)
|
481
|
+
else
|
482
|
+
options.dup
|
483
|
+
end
|
251
484
|
end
|
252
485
|
|
253
|
-
|
486
|
+
# Expand a key to be a consistent string value. If the object responds to +cache_key+,
|
487
|
+
# it will be called. Otherwise, the to_param method will be called. If the key is a
|
488
|
+
# Hash, the keys will be sorted alphabetically.
|
489
|
+
def expanded_key(key) # :nodoc:
|
490
|
+
if key.respond_to?(:cache_key)
|
491
|
+
key = key.cache_key.to_s
|
492
|
+
elsif key.is_a?(Array)
|
493
|
+
if key.size > 1
|
494
|
+
key.collect{|element| expanded_key(element)}.to_param
|
495
|
+
else
|
496
|
+
key.first.to_param
|
497
|
+
end
|
498
|
+
elsif key.is_a?(Hash)
|
499
|
+
key = key.to_a.sort{|a,b| a.first.to_s <=> b.first.to_s}.collect{|k,v| "#{k}=#{v}"}.to_param
|
500
|
+
else
|
501
|
+
key = key.to_param
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
# Prefix a key with the namespace. The two values will be delimited with a colon.
|
506
|
+
def namespaced_key(key, options)
|
507
|
+
key = expanded_key(key)
|
508
|
+
namespace = options[:namespace] if options
|
509
|
+
prefix = namespace.is_a?(Proc) ? namespace.call : namespace
|
510
|
+
key = "#{prefix}:#{key}" if prefix
|
511
|
+
key
|
512
|
+
end
|
513
|
+
|
514
|
+
def instrument(operation, key, options = nil)
|
254
515
|
log(operation, key, options)
|
255
516
|
|
256
517
|
if self.class.instrument
|
257
518
|
payload = { :key => key }
|
258
519
|
payload.merge!(options) if options.is_a?(Hash)
|
259
|
-
ActiveSupport::Notifications.instrument(
|
520
|
+
ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
|
260
521
|
else
|
261
|
-
yield
|
522
|
+
yield(nil)
|
262
523
|
end
|
263
524
|
end
|
264
525
|
|
265
|
-
def log(operation, key, options)
|
266
|
-
return unless logger && !silence?
|
267
|
-
logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})"
|
526
|
+
def log(operation, key, options = nil)
|
527
|
+
return unless logger && logger.debug? && !silence?
|
528
|
+
logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}")
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
# Entry that is put into caches. It supports expiration time on entries and can compress values
|
533
|
+
# to save space in the cache.
|
534
|
+
class Entry
|
535
|
+
attr_reader :created_at, :expires_in
|
536
|
+
|
537
|
+
DEFAULT_COMPRESS_LIMIT = 16.kilobytes
|
538
|
+
|
539
|
+
class << self
|
540
|
+
# Create an entry with internal attributes set. This method is intended to be
|
541
|
+
# used by implementations that store cache entries in a native format instead
|
542
|
+
# of as serialized Ruby objects.
|
543
|
+
def create (raw_value, created_at, options = {})
|
544
|
+
entry = new(nil)
|
545
|
+
entry.instance_variable_set(:@value, raw_value)
|
546
|
+
entry.instance_variable_set(:@created_at, created_at.to_f)
|
547
|
+
entry.instance_variable_set(:@compressed, !!options[:compressed])
|
548
|
+
entry.instance_variable_set(:@expires_in, options[:expires_in])
|
549
|
+
entry
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
# Create a new cache entry for the specified value. Options supported are
|
554
|
+
# +:compress+, +:compress_threshold+, and +:expires_in+.
|
555
|
+
def initialize(value, options = {})
|
556
|
+
@compressed = false
|
557
|
+
@expires_in = options[:expires_in]
|
558
|
+
@expires_in = @expires_in.to_f if @expires_in
|
559
|
+
@created_at = Time.now.to_f
|
560
|
+
if value
|
561
|
+
if should_compress?(value, options)
|
562
|
+
@value = Zlib::Deflate.deflate(Marshal.dump(value))
|
563
|
+
@compressed = true
|
564
|
+
else
|
565
|
+
@value = value
|
566
|
+
end
|
567
|
+
else
|
568
|
+
@value = nil
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
# Get the raw value. This value may be serialized and compressed.
|
573
|
+
def raw_value
|
574
|
+
@value
|
575
|
+
end
|
576
|
+
|
577
|
+
# Get the value stored in the cache.
|
578
|
+
def value
|
579
|
+
if @value
|
580
|
+
val = compressed? ? Marshal.load(Zlib::Inflate.inflate(@value)) : @value
|
581
|
+
unless val.frozen?
|
582
|
+
val.freeze rescue nil
|
583
|
+
end
|
584
|
+
val
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
def compressed?
|
589
|
+
@compressed
|
590
|
+
end
|
591
|
+
|
592
|
+
# Check if the entry is expired. The +expires_in+ parameter can override the
|
593
|
+
# value set when the entry was created.
|
594
|
+
def expired?
|
595
|
+
if @expires_in && @created_at + @expires_in <= Time.now.to_f
|
596
|
+
true
|
597
|
+
else
|
598
|
+
false
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
# Set a new time to live on the entry so it expires at the given time.
|
603
|
+
def expires_at=(time)
|
604
|
+
if time
|
605
|
+
@expires_in = time.to_f - @created_at
|
606
|
+
else
|
607
|
+
@expires_in = nil
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
# Seconds since the epoch when the cache entry will expire.
|
612
|
+
def expires_at
|
613
|
+
@expires_in ? @created_at + @expires_in : nil
|
614
|
+
end
|
615
|
+
|
616
|
+
# Get the size of the cached value. This could be less than value.size
|
617
|
+
# if the data is compressed.
|
618
|
+
def size
|
619
|
+
if @value.nil?
|
620
|
+
0
|
621
|
+
elsif @value.respond_to?(:bytesize)
|
622
|
+
@value.bytesize
|
623
|
+
else
|
624
|
+
Marshal.dump(@value).bytesize
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
private
|
629
|
+
def should_compress?(value, options)
|
630
|
+
if options[:compress] && value
|
631
|
+
unless value.is_a?(Numeric)
|
632
|
+
compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT
|
633
|
+
serialized_value = value.is_a?(String) ? value : Marshal.dump(value)
|
634
|
+
return true if serialized_value.size >= compress_threshold
|
635
|
+
end
|
636
|
+
end
|
637
|
+
false
|
268
638
|
end
|
269
639
|
end
|
270
640
|
end
|