ref: master
lib/noosfero/scheduler/defer.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# based on https://github.com/discourse/discourse/blob/master/lib/scheduler/defer.rb module Noosfero module Scheduler module Deferrable def initialize # FIXME: do some other way when not using Unicorn @async = (not Rails.env.test?) and defined? Unicorn @queue = Queue.new @mutex = Mutex.new @paused = false @thread = nil end def pause stop! @paused = true end def resume @paused = false end # for test def async= val @async = val end def later desc = nil, &blk if @async start_thread unless (@thread && @thread.alive?) || @paused @queue << [blk, desc] else blk.call end end def stop! @thread.kill if @thread and @thread.alive? @thread = nil end # test only def stopped? !(@thread and @thread.alive?) end def do_all_work while !@queue.empty? do_work _non_block=true end end private def start_thread @mutex.synchronize do return if @thread && @thread.alive? @thread = Thread.new do while true do_work end end @thread.priority = -2 end end # using non_block to match Ruby #deq def do_work non_block=false job, desc = @queue.deq non_block begin job.call rescue => ex ExceptionNotifier.notify_exception ex, message: "Running deferred code '#{desc}'" end rescue => ex ExceptionNotifier.notify_exception ex, message: "Processing deferred code queue" end end class Defer module Unicorn def process_client client ::Noosfero::Scheduler::Defer.pause super client ::Noosfero::Scheduler::Defer.do_all_work ::Noosfero::Scheduler::Defer.resume end end extend Deferrable initialize end end end |