@@ -35,22 +35,27 @@ class Store # :nodoc:
35
35
alias_method :enabled? , :enabled
36
36
alias_method :dirties? , :dirties
37
37
38
- def initialize ( max_size )
38
+ def initialize ( pool , max_size )
39
+ @pool = pool
40
+ @version = pool . query_cache_version
39
41
@map = { }
40
42
@max_size = max_size
41
43
@enabled = false
42
44
@dirties = true
43
45
end
44
46
45
47
def size
48
+ check_version
46
49
@map . size
47
50
end
48
51
49
52
def empty?
53
+ check_version
50
54
@map . empty?
51
55
end
52
56
53
57
def []( key )
58
+ check_version
54
59
return unless @enabled
55
60
56
61
if entry = @map . delete ( key )
@@ -59,6 +64,7 @@ def [](key)
59
64
end
60
65
61
66
def compute_if_absent ( key )
67
+ check_version
62
68
return yield unless @enabled
63
69
64
70
if entry = @map . delete ( key )
@@ -76,12 +82,21 @@ def clear
76
82
@map . clear
77
83
self
78
84
end
85
+
86
+ private
87
+ def check_version
88
+ version = @pool . query_cache_version
89
+ if version != @version
90
+ @map . clear
91
+ @version = version
92
+ end
93
+ end
79
94
end
80
95
81
96
module ConnectionPoolConfiguration # :nodoc:
82
97
def initialize ( ...)
83
98
super
84
- @thread_query_caches = Concurrent :: Map . new ( initial_capacity : @size )
99
+ @query_cache_version = 0
85
100
@query_cache_max_size = \
86
101
case query_cache = db_config &.query_cache
87
102
when 0 , false
@@ -93,6 +108,10 @@ def initialize(...)
93
108
end
94
109
end
95
110
111
+ def query_cache_version
112
+ synchronize { @query_cache_version }
113
+ end
114
+
96
115
def checkout_and_verify ( connection )
97
116
super
98
117
connection . query_cache ||= query_cache
@@ -141,25 +160,17 @@ def clear_query_cache
141
160
# With transactional fixtures, and especially systems test
142
161
# another thread may use the same connection, but with a different
143
162
# query cache. So we must clear them all.
144
- @thread_query_caches . each_value ( & :clear )
145
- else
146
- query_cache . clear
163
+ synchronize do
164
+ @query_cache_version += 1
165
+ end
147
166
end
167
+ query_cache . clear
148
168
end
149
169
150
170
def query_cache
151
- @thread_query_caches . compute_if_absent ( ActiveSupport ::IsolatedExecutionState . context ) do
152
- Store . new ( @query_cache_max_size )
153
- end
171
+ key = :"active_record_query_cache_#{ object_id } "
172
+ ActiveSupport ::IsolatedExecutionState [ key ] ||= Store . new ( self , @query_cache_max_size )
154
173
end
155
-
156
- private
157
- def prune_thread_cache
158
- dead_threads = @thread_query_caches . keys . reject ( &:alive? )
159
- dead_threads . each do |dead_thread |
160
- @thread_query_caches . delete ( dead_thread )
161
- end
162
- end
163
174
end
164
175
165
176
attr_accessor :query_cache
0 commit comments