Add Rails 6 backport for ActiveRecord
This fixes the "can't create Thread: Resource temporarily unavailable" error.
This commit is contained in:
parent
0d6a3c14e9
commit
06b035f2ea
2 changed files with 100 additions and 0 deletions
|
@ -215,6 +215,7 @@ Lint/ShadowingOuterLocalVariable:
|
||||||
# Configuration parameters: AllowComments, AllowNil.
|
# Configuration parameters: AllowComments, AllowNil.
|
||||||
Lint/SuppressedException:
|
Lint/SuppressedException:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
- 'config/initializers/rails6_backports.rb'
|
||||||
- 'lib/foodsoft_config.rb'
|
- 'lib/foodsoft_config.rb'
|
||||||
- 'lib/tasks/rspec.rake'
|
- 'lib/tasks/rspec.rake'
|
||||||
|
|
||||||
|
@ -1495,6 +1496,7 @@ Style/MultilineBlockChain:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/helpers/group_orders_helper.rb'
|
- 'app/helpers/group_orders_helper.rb'
|
||||||
- 'app/models/order.rb'
|
- 'app/models/order.rb'
|
||||||
|
- 'config/initializers/rails6_backports.rb'
|
||||||
|
|
||||||
# Offense count: 2
|
# Offense count: 2
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
|
|
98
config/initializers/rails6_backports.rb
Normal file
98
config/initializers/rails6_backports.rb
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
raise "Remove no-longer-needed #{__FILE__}!" if Rails::VERSION::MAJOR >= 6
|
||||||
|
|
||||||
|
require "weakref"
|
||||||
|
|
||||||
|
module ActiveRecord
|
||||||
|
# Backport https://github.com/rails/rails/pull/36998 and https://github.com/rails/rails/pull/36999
|
||||||
|
# to avoid `ThreadError: can't create Thread: Resource temporarily unavailable` issues
|
||||||
|
module ConnectionAdapters
|
||||||
|
class ConnectionPool
|
||||||
|
class Reaper
|
||||||
|
@mutex = Mutex.new
|
||||||
|
@pools = {}
|
||||||
|
@threads = {}
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def register_pool(pool, frequency) # :nodoc:
|
||||||
|
@mutex.synchronize do
|
||||||
|
unless @threads[frequency]&.alive?
|
||||||
|
@threads[frequency] = spawn_thread(frequency)
|
||||||
|
end
|
||||||
|
@pools[frequency] ||= []
|
||||||
|
@pools[frequency] << WeakRef.new(pool)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def spawn_thread(frequency)
|
||||||
|
Thread.new(frequency) do |t|
|
||||||
|
running = true
|
||||||
|
while running
|
||||||
|
sleep t
|
||||||
|
@mutex.synchronize do
|
||||||
|
@pools[frequency].select!(&:weakref_alive?)
|
||||||
|
@pools[frequency].each do |p|
|
||||||
|
p.reap
|
||||||
|
p.flush
|
||||||
|
rescue WeakRef::RefError
|
||||||
|
end
|
||||||
|
|
||||||
|
if @pools[frequency].empty?
|
||||||
|
@pools.delete(frequency)
|
||||||
|
@threads.delete(frequency)
|
||||||
|
running = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
return unless frequency && frequency > 0
|
||||||
|
|
||||||
|
self.class.register_pool(pool, frequency)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reap
|
||||||
|
stale_connections = synchronize do
|
||||||
|
return unless @connections
|
||||||
|
|
||||||
|
@connections.select do |conn|
|
||||||
|
conn.in_use? && !conn.owner.alive?
|
||||||
|
end.each(&:steal!)
|
||||||
|
end
|
||||||
|
|
||||||
|
stale_connections.each do |conn|
|
||||||
|
if conn.active?
|
||||||
|
conn.reset!
|
||||||
|
checkin conn
|
||||||
|
else
|
||||||
|
remove conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def flush(minimum_idle = @idle_timeout)
|
||||||
|
return if minimum_idle.nil?
|
||||||
|
|
||||||
|
idle_connections = synchronize do
|
||||||
|
return unless @connections
|
||||||
|
|
||||||
|
@connections.select do |conn|
|
||||||
|
!conn.in_use? && conn.seconds_idle >= minimum_idle
|
||||||
|
end.each do |conn|
|
||||||
|
conn.lease
|
||||||
|
|
||||||
|
@available.delete conn
|
||||||
|
@connections.delete conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
idle_connections.each(&:disconnect!)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue