2014-03-16 20:59:34 -04:00
|
|
|
module Scheduler
|
|
|
|
module Deferrable
|
|
|
|
def initialize
|
2014-08-18 02:42:48 -04:00
|
|
|
@async = !Rails.env.test?
|
2014-03-16 20:59:34 -04:00
|
|
|
@queue = Queue.new
|
2014-03-17 00:22:11 -04:00
|
|
|
@mutex = Mutex.new
|
2015-02-16 17:56:21 -05:00
|
|
|
@paused = false
|
2014-03-17 00:22:11 -04:00
|
|
|
@thread = nil
|
2015-02-16 17:56:21 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def pause
|
|
|
|
stop!
|
|
|
|
@paused = true
|
|
|
|
end
|
2014-03-17 00:22:11 -04:00
|
|
|
|
2015-02-16 17:56:21 -05:00
|
|
|
def resume
|
|
|
|
@paused = false
|
2014-03-16 20:59:34 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# for test
|
|
|
|
def async=(val)
|
|
|
|
@async = val
|
|
|
|
end
|
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
def later(desc = nil, db = RailsMultisite::ConnectionManagement.current_db, &blk)
|
2014-03-16 20:59:34 -04:00
|
|
|
if @async
|
2015-02-16 17:56:21 -05:00
|
|
|
start_thread unless (@thread && @thread.alive?) || @paused
|
2015-02-05 00:08:52 -05:00
|
|
|
@queue << [db, blk, desc]
|
2014-03-16 20:59:34 -04:00
|
|
|
else
|
|
|
|
blk.call
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def stop!
|
2015-02-16 17:56:21 -05:00
|
|
|
@thread.kill if @thread && @thread.alive?
|
|
|
|
@thread = nil
|
2014-03-16 20:59:34 -04:00
|
|
|
end
|
|
|
|
|
2014-03-17 00:22:11 -04:00
|
|
|
# test only
|
|
|
|
def stopped?
|
2015-02-16 17:56:21 -05:00
|
|
|
!(@thread && @thread.alive?)
|
|
|
|
end
|
|
|
|
|
|
|
|
def do_all_work
|
|
|
|
while !@queue.empty?
|
2017-07-27 21:20:09 -04:00
|
|
|
do_work(_non_block = true)
|
2015-02-16 17:56:21 -05:00
|
|
|
end
|
2014-03-17 00:22:11 -04:00
|
|
|
end
|
|
|
|
|
2014-03-16 20:59:34 -04:00
|
|
|
private
|
|
|
|
|
2014-03-17 00:22:11 -04:00
|
|
|
def start_thread
|
|
|
|
@mutex.synchronize do
|
|
|
|
return if @thread && @thread.alive?
|
|
|
|
@thread = Thread.new {
|
|
|
|
while true
|
|
|
|
do_work
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-16 17:56:21 -05:00
|
|
|
# using non_block to match Ruby #deq
|
2017-07-27 21:20:09 -04:00
|
|
|
def do_work(non_block = false)
|
2015-02-16 17:56:21 -05:00
|
|
|
db, job, desc = @queue.deq(non_block)
|
2017-10-11 05:19:26 -04:00
|
|
|
db ||= RailsMultisite::ConnectionManagement::DEFAULT
|
2017-10-11 05:17:03 -04:00
|
|
|
|
2017-10-11 05:45:19 -04:00
|
|
|
RailsMultisite::ConnectionManagement.with_connection(db) do
|
2017-10-11 05:19:26 -04:00
|
|
|
begin
|
2017-10-11 05:17:03 -04:00
|
|
|
job.call
|
2017-10-11 05:19:26 -04:00
|
|
|
rescue => ex
|
|
|
|
Discourse.handle_job_exception(ex, message: "Running deferred code '#{desc}'")
|
2017-10-11 05:17:03 -04:00
|
|
|
end
|
2014-07-17 16:22:46 -04:00
|
|
|
end
|
2014-03-16 20:59:34 -04:00
|
|
|
rescue => ex
|
2017-07-27 21:20:09 -04:00
|
|
|
Discourse.handle_job_exception(ex, message: "Processing deferred code queue")
|
2017-10-29 23:24:15 -04:00
|
|
|
ensure
|
|
|
|
ActiveRecord::Base.connection_handler.clear_active_connections!
|
2014-03-16 20:59:34 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Defer
|
2015-02-16 17:56:21 -05:00
|
|
|
|
|
|
|
module Unicorn
|
|
|
|
def process_client(client)
|
|
|
|
Defer.pause
|
|
|
|
super(client)
|
|
|
|
Defer.do_all_work
|
|
|
|
Defer.resume
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-03-16 20:59:34 -04:00
|
|
|
extend Deferrable
|
|
|
|
initialize
|
|
|
|
end
|
|
|
|
end
|