module Scheduler module Deferrable def initialize @async = Rails.env != "test" @queue = Queue.new @mutex = Mutex.new @thread = nil start_thread end # for test def async=(val) @async = val end def later(&blk) if @async start_thread unless @thread.alive? @queue << [RailsMultisite::ConnectionManagement.current_db, blk] else blk.call end end def stop! @thread.kill end # test only def stopped? !@thread.alive? end private def start_thread @mutex.synchronize do return if @thread && @thread.alive? @thread = Thread.new { while true do_work end } end end def do_work db, job = @queue.deq RailsMultisite::ConnectionManagement.establish_connection(db: db) job.call rescue => ex Discourse.handle_exception(ex) ensure ActiveRecord::Base.connection_handler.clear_active_connections! end end class Defer extend Deferrable initialize end end