mirror of
https://github.com/cyberarm/w3d_hub_linux_launcher.git
synced 2025-12-15 08:42:34 +00:00
167 lines
3.5 KiB
Ruby
167 lines
3.5 KiB
Ruby
class W3DHub
|
|
class BackgroundWorker
|
|
LOG_TAG = "W3DHub::BackgroundWorker"
|
|
@@instance = nil
|
|
@@alive = false
|
|
|
|
def self.create
|
|
raise "BackgroundWorker instance already exists!" if @@instance
|
|
logger.info(LOG_TAG) { "Starting background job worker..." }
|
|
|
|
|
|
@@thread = Thread.current
|
|
@@alive = true
|
|
@@run = true
|
|
@@instance = self.new
|
|
|
|
@@instance.handle_jobs
|
|
end
|
|
|
|
def self.instance
|
|
@@instance
|
|
end
|
|
|
|
def self.run?
|
|
@@run
|
|
end
|
|
|
|
def self.alive?
|
|
@@alive
|
|
end
|
|
|
|
def self.busy?
|
|
instance&.busy?
|
|
end
|
|
|
|
def self.shutdown!
|
|
@@run = false
|
|
end
|
|
|
|
def self.kill!
|
|
@@thread.kill
|
|
|
|
@@instance.kill!
|
|
end
|
|
|
|
def self.job(job, callback, error_handler = nil, data = nil)
|
|
@@instance.add_job(Job.new(job: job, callback: callback, error_handler: error_handler, data: data))
|
|
end
|
|
|
|
def self.parallel_job(job, callback, error_handler = nil, data = nil)
|
|
@@instance.add_parallel_job(Job.new(job: job, callback: callback, error_handler: error_handler, data: data))
|
|
end
|
|
|
|
def self.foreground_job(job, callback, error_handler = nil, data = nil)
|
|
@@instance.add_job(Job.new(job: job, callback: callback, error_handler: error_handler, deliver_to_queue: true, data: data))
|
|
end
|
|
|
|
def self.foreground_parallel_job(job, callback, error_handler = nil, data = nil)
|
|
@@instance.add_parallel_job(Job.new(job: job, callback: callback, error_handler: error_handler, deliver_to_queue: true, data: data))
|
|
end
|
|
|
|
def initialize
|
|
@busy = false
|
|
@jobs = []
|
|
|
|
# Jobs which are order independent
|
|
@parallel_busy = false
|
|
@thread_pool = []
|
|
@parallel_jobs = []
|
|
end
|
|
|
|
def kill!
|
|
@thread_pool.each(&:kill)
|
|
|
|
logger.info(LOG_TAG) { "Forcefully killed background job worker." }
|
|
@@alive = false
|
|
end
|
|
|
|
def handle_jobs
|
|
8.times do |i|
|
|
Thread.new do
|
|
@thread_pool << Thread.current
|
|
|
|
while BackgroundWorker.run?
|
|
job = @parallel_jobs.shift
|
|
|
|
@parallel_busy = true
|
|
|
|
begin
|
|
job&.do
|
|
rescue => e
|
|
job&.raise_error(e)
|
|
end
|
|
|
|
@parallel_busy = !@parallel_jobs.empty?
|
|
|
|
sleep 0.1
|
|
end
|
|
end
|
|
end
|
|
|
|
Thread.new do
|
|
@thread_pool << Thread.current
|
|
|
|
while BackgroundWorker.run?
|
|
job = @jobs.shift
|
|
|
|
@busy = true
|
|
|
|
begin
|
|
job&.do
|
|
rescue => e
|
|
job&.raise_error(e)
|
|
end
|
|
|
|
@busy = !@jobs.empty?
|
|
|
|
sleep 0.1
|
|
end
|
|
|
|
logger.info(LOG_TAG) { "Stopped background job worker." }
|
|
@@alive = false
|
|
end
|
|
end
|
|
|
|
def add_job(job)
|
|
@jobs << job
|
|
end
|
|
|
|
def add_parallel_job(job)
|
|
@parallel_jobs << job
|
|
end
|
|
|
|
def busy?
|
|
@busy || @parallel_busy
|
|
end
|
|
|
|
class Job
|
|
def initialize(job:, callback:, error_handler: nil, deliver_to_queue: false, data: nil)
|
|
@job = job
|
|
@callback = callback
|
|
@error_handler = error_handler
|
|
@deliver_to_queue = deliver_to_queue
|
|
@data = data
|
|
end
|
|
|
|
def do
|
|
result = @data ? @job.call(@data) : @job.call
|
|
deliver(result)
|
|
end
|
|
|
|
def deliver(result)
|
|
if @deliver_to_queue
|
|
Store.main_thread_queue << -> { @callback.call(result) }
|
|
else
|
|
@callback.call(result)
|
|
end
|
|
end
|
|
|
|
def raise_error(error)
|
|
logger.error error
|
|
@error_handler&.call(error)
|
|
end
|
|
end
|
|
end
|
|
end
|