Browse files

LRU should cache per process in postgresql. fixes #1339

  • Loading branch information...
1 parent 8e79c52 commit 834d429e849b590ee7a283909eda9affed065387 @tenderlove tenderlove committed Sep 7, 2011
View
24 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -251,34 +251,38 @@ class StatementPool < ConnectionAdapters::StatementPool
def initialize(connection, max)
super
@counter = 0
- @cache = {}
+ @cache = Hash.new { |h,pid| h[pid] = {} }
end
- def each(&block); @cache.each(&block); end
- def key?(key); @cache.key?(key); end
- def [](key); @cache[key]; end
- def length; @cache.length; end
+ def each(&block); cache.each(&block); end
+ def key?(key); cache.key?(key); end
+ def [](key); cache[key]; end
+ def length; cache.length; end
def next_key
"a#{@counter + 1}"
end
def []=(sql, key)
- while @max <= @cache.size
- dealloc(@cache.shift.last)
+ while @max <= cache.size
+ dealloc(cache.shift.last)
end
@counter += 1
- @cache[sql] = key
+ cache[sql] = key
end
def clear
- @cache.each_value do |stmt_key|
+ cache.each_value do |stmt_key|
dealloc stmt_key
end
- @cache.clear
+ cache.clear
end
private
+ def cache
+ @cache[$$]
+ end
+
def dealloc(key)
@connection.query "DEALLOCATE #{key}"
end
View
23 activerecord/test/cases/adapters/postgresql/statement_cache_test.rb
@@ -0,0 +1,23 @@
+require 'cases/helper'
+
+module ActiveRecord::ConnectionAdapters
+ class PostgreSQLAdapter < AbstractAdapter
+ class StatementPoolTest < ActiveRecord::TestCase
+ def test_cache_is_per_pid
+ return skip('must support fork') unless Process.respond_to?(:fork)
+
+ cache = StatementPool.new nil, 10
+ cache['foo'] = 'bar'
+ assert_equal 'bar', cache['foo']
+
+ pid = fork {
+ lookup = cache['foo'];
+ exit!(!lookup)
+ }
+
+ Process.waitpid pid
+ assert $?.success?, 'process should exit successfully'
+ end
+ end
+ end
+end

0 comments on commit 834d429

Please sign in to comment.