FEATURE: add a simple queue Scheduler::Defer.later {}
For quick jobs that do not need to be sent to sidekiq, runs inline in a single thread but does not block
This commit is contained in:
parent
fe63db7953
commit
2c8ae22b87
|
@ -33,9 +33,12 @@ class Auth::DefaultCurrentUserProvider
|
|||
|
||||
if current_user
|
||||
|
||||
Jobs.enqueue(:update_user_info,
|
||||
user_id: current_user.id,
|
||||
ip: request.ip)
|
||||
u = current_user
|
||||
Scheduler::Defer.later do
|
||||
u.update_last_seen!
|
||||
u.update_ip_address!(request.ip)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# possible we have an api call, impersonate
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
module Scheduler
|
||||
module Deferrable
|
||||
def initialize
|
||||
@async = Rails.env != "test"
|
||||
@queue = Queue.new
|
||||
@thread = Thread.new {
|
||||
while true
|
||||
do_work
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# for test
|
||||
def async=(val)
|
||||
@async = val
|
||||
end
|
||||
|
||||
def later(&blk)
|
||||
if @async
|
||||
@queue << [RailsMultisite::ConnectionManagement.current_db, blk]
|
||||
else
|
||||
blk.call
|
||||
end
|
||||
end
|
||||
|
||||
def stop!
|
||||
@thread.kill
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
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
|
|
@ -4,3 +4,4 @@ end
|
|||
require_dependency 'scheduler/schedule'
|
||||
require_dependency 'scheduler/schedule_info'
|
||||
require_dependency 'scheduler/manager'
|
||||
require_dependency 'scheduler/defer'
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# encoding: utf-8
|
||||
require 'spec_helper'
|
||||
require 'scheduler/scheduler'
|
||||
|
||||
describe Scheduler::Defer do
|
||||
class DeferInstance
|
||||
include Scheduler::Deferrable
|
||||
end
|
||||
|
||||
def wait_for(timeout, &blk)
|
||||
till = Time.now + (timeout.to_f / 1000)
|
||||
while Time.now < till && !blk.call
|
||||
sleep 0.001
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
@defer = DeferInstance.new
|
||||
@defer.async = true
|
||||
end
|
||||
|
||||
after do
|
||||
@defer.stop!
|
||||
end
|
||||
|
||||
it "can queue jobs properly" do
|
||||
s = nil
|
||||
|
||||
@defer.later do
|
||||
s = "good"
|
||||
end
|
||||
|
||||
wait_for(10) do
|
||||
s == "good"
|
||||
end
|
||||
|
||||
s.should == "good"
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue