class MU::Thread
Subclass core thread so we can gracefully handle it when we hit system thread limits. Back off and wait makes sense for us, since most of our threads are terminal (in the dependency sense) and this is unlikely to get us deadlocks.
Public Class Methods
new(*args, &block)
click to toggle source
Calls superclass method
# File modules/mu.rb, line 237 def initialize(*args, &block) @@mu_global_thread_semaphore.synchronize { @@mu_global_threads.reject! { |t| t.nil? or !t.status } } newguy = nil start = Time.now begin newguy = super(*args, &block) if newguy.nil? MU.log "I somehow got a nil trying to create a thread", MU::WARN, details: caller sleep 1 end rescue ::ThreadError => e if e.message.match(/Resource temporarily unavailable/) toomany = @@mu_global_threads.size MU.log "Hit the wall at #{toomany.to_s} threads, waiting until there are fewer", MU::WARN if @@mu_global_threads.size >= toomany sleep 1 begin @@mu_global_thread_semaphore.synchronize { @@mu_global_threads.each { |t| next if t == ::Thread.current t.join(0.1) } @@mu_global_threads.reject! { |t| t.nil? or !t.status } } if (Time.now - start) > 150 MU.log "Failed to get a free thread slot after 150 seconds- are we in a deadlock situation?", MU::ERR, details: caller raise e end end while @@mu_global_threads.size >= toomany end retry else raise e end end while newguy.nil? @@mu_global_thread_semaphore.synchronize { MU.dupGlobals(Thread.current.object_id, target_thread: newguy) @@mu_global_threads << newguy } end