module SoarThreadWorker class ThreadWorker attr_accessor :event_handler attr_accessor :thread def self.create_worker(event_handler) ThreadWorker.new(event_handler) end def self.error(message) $stderr.puts "ERROR [ThreadWorker] #{message}" end def initialize(event_handler: nil) @api_mutex = Mutex.new @stopping = false @event_handler = event_handler end def running? (not @thread.nil?) and @thread.alive? end def start @api_mutex.synchronize { begin return if (running?) @stopping = false create_thread() rescue Exception => e ThreadWorker::error("Exception #{e} in start") end } end def stop(immediate: false) @api_mutex.synchronize { @stopping = true @thread.kill if (not @thread.nil?) and immediate } end def execute #Inversion of control: override this method to do the work you need. #Return true if after execution the thread should stop, false if it #should continue running false end private def run while not @stopping stop if execute be_nice end end def create_thread @thread = Thread.new do Thread.abort_on_exception=true run end end def be_nice sleep(0.01) Thread.pass end end end