From 90f6062f7d5893f11ef186e80a91269421dc6f65 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 28 Apr 2008 11:59:55 -0700 Subject: [PATCH 1/7] run prepare callbacks after after_initialize blocks so config.to_prepare actually works --- railties/lib/initializer.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb index e36f917b15be0..ea61d4e4feaa6 100644 --- a/railties/lib/initializer.rb +++ b/railties/lib/initializer.rb @@ -135,12 +135,12 @@ def process load_application_initializers - # Prepare dispatcher callbacks and run 'prepare' callbacks - prepare_dispatcher - # the framework is now fully initialized after_initialize + # Prepare dispatcher callbacks and run 'prepare' callbacks + prepare_dispatcher + # Routing must be initialized after plugins to allow the former to extend the routes initialize_routing From 1c66ece244824aa1a1d665c76033821424f1c41c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 28 Apr 2008 22:05:06 -0700 Subject: [PATCH 2/7] Note that allow_concurrency = true means you need to verify_active_connections! to clear out connections assigned to stale threads. --- activerecord/lib/active_record/base.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 300688453ad49..63306644fbeca 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -423,7 +423,9 @@ def self.reset_subclasses #:nodoc: @@default_timezone = :local # Determines whether to use a connection for each thread, or a single shared connection for all threads. - # Defaults to false. Set to true if you're writing a threaded application. + # Defaults to false. If you're writing a threaded application, set to true + # and periodically call verify_active_connections! to clear out connections + # assigned to stale threads. cattr_accessor :allow_concurrency, :instance_writer => false @@allow_concurrency = false From bfb54aefa6bbff194eeb81b8e797ddde24aaae95 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 28 Apr 2008 22:10:19 -0700 Subject: [PATCH 3/7] Clarify confusing ActionController::Base.allow_concurrency flag. --- actionpack/lib/action_controller/base.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 0c0d0ec4ac86c..3322a41299cc3 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -277,9 +277,10 @@ class Base @@debug_routes = true cattr_accessor :debug_routes - # Controls whether the application is thread-safe, so multi-threaded servers like WEBrick know whether to apply a mutex - # around the performance of each action. Action Pack and Active Record are by default thread-safe, but many applications - # may not be. Turned off by default. + # Indicates to Mongrel or Webrick whether to allow concurrent action + # processing. Your controller actions and any other code they call must + # also behave well when called from concurrent threads. Turned off by + # default. @@allow_concurrency = false cattr_accessor :allow_concurrency From 9f07b1edcd2955dc7af166c422309da55372a92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=BCtke?= Date: Tue, 29 Apr 2008 14:57:21 -0400 Subject: [PATCH 4/7] By default rails will update keys in memcached when using Rails.cache.write. Use :unless_exist => true flag to prevent existing keys from being overwritten. --- .../lib/active_support/cache/mem_cache_store.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index 9b787702b2007..ad220a9c2c224 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -29,12 +29,11 @@ def read(key, options = nil) nil end - # Set key = value if key isn't already set. Pass :force => true - # to unconditionally set key = value. Returns a boolean indicating - # whether the key was set. + # Set key = value. Pass :unless_exist => true if you don't + # want to update the cache if the key is already set. def write(key, value, options = nil) super - method = options && options[:force] ? :set : :add + method = options && options[:unless_exist] ? :add : :set response = @data.send(method, key, value, expires_in(options), raw?(options)) response == Response::STORED rescue MemCache::MemCacheError => e @@ -54,8 +53,8 @@ def delete(key, options = nil) def delete_matched(matcher, options = nil) super raise "Not supported by Memcache" - end - + end + def clear @data.flush_all end From fef82759ff97692470496905951882a0aab49d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=BCtke?= Date: Tue, 29 Apr 2008 15:12:47 -0400 Subject: [PATCH 5/7] Implement increment/decrement on cache storage engines, using read/write by default and using atomic command on memcache --- .../controller/session/mem_cache_store_test.rb | 5 ++--- activesupport/lib/active_support/cache.rb | 17 +++++++++++++++++ .../active_support/cache/mem_cache_store.rb | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/actionpack/test/controller/session/mem_cache_store_test.rb b/actionpack/test/controller/session/mem_cache_store_test.rb index df48e6d9c52a2..a7d48431f8e93 100644 --- a/actionpack/test/controller/session/mem_cache_store_test.rb +++ b/actionpack/test/controller/session/mem_cache_store_test.rb @@ -62,9 +62,8 @@ def test_storage assert_equal d, s.cache.get(session_key)[:test] assert_equal d, s[:test] end - end - - + end + def test_deletion new_session do |s| session_key = 'session:' + s.session_id diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 64394afec444f..463cba6cf0ad7 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -87,8 +87,25 @@ def delete(key, options = nil) def delete_matched(matcher, options = nil) log("delete matched", matcher.inspect, options) + end + + def increment(key, amount = 1) + log("incrementing", key, amount) + if num = read(key) + write(key, num + amount) + else + nil + end end + def decrement(key, amount = 1) + log("decrementing", key, amount) + if num = read(key) + write(key, num - amount) + else + nil + end + end private def log(operation, key, options) diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index ad220a9c2c224..15e2df13b3e38 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -48,8 +48,26 @@ def delete(key, options = nil) rescue MemCache::MemCacheError => e logger.error("MemCacheError (#{e}): #{e.message}") false + end + + def increment(key, amount = 1) + log("incrementing", key, amount) + + response = @data.incr(key, amount) + response == Response::NOT_FOUND ? nil : response + rescue MemCache::MemCacheError + nil end + def decrement(key, amount = 1) + log("decrement", key, amount) + + response = data.decr(key, amount) + response == Response::NOT_FOUND ? nil : response + rescue MemCache::MemCacheError + nil + end + def delete_matched(matcher, options = nil) super raise "Not supported by Memcache" From 09517e3aeadba204d5b0b8c45a03e8084c4fc0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=BCtke?= Date: Tue, 29 Apr 2008 15:28:24 -0400 Subject: [PATCH 6/7] Allow access to mem_cache_store's stats hash --- activesupport/lib/active_support/cache/mem_cache_store.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb index 15e2df13b3e38..bfe7e2ccf3923 100644 --- a/activesupport/lib/active_support/cache/mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/mem_cache_store.rb @@ -75,6 +75,10 @@ def delete_matched(matcher, options = nil) def clear @data.flush_all + end + + def stats + @data.stats end private From 5be53058775a1482c1e5655dcb0ca4430cf0dbe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=BCtke?= Date: Tue, 29 Apr 2008 16:34:01 -0400 Subject: [PATCH 7/7] Add missing clear method to memory_store --- activesupport/lib/active_support/cache/memory_store.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb index e0aba6b19a063..4872e025cd307 100644 --- a/activesupport/lib/active_support/cache/memory_store.rb +++ b/activesupport/lib/active_support/cache/memory_store.rb @@ -24,6 +24,10 @@ def delete_matched(matcher, options = nil) super @data.delete_if { |k,v| k =~ matcher } end + + def clear + @data.clear + end end end end \ No newline at end of file