Skip to content

Instantly share code, notes, and snippets.

@mgreenly
Created March 2, 2021 03:19
Show Gist options
  • Save mgreenly/f8c01506c47968e7c7b445b773d92236 to your computer and use it in GitHub Desktop.
Save mgreenly/f8c01506c47968e7c7b445b773d92236 to your computer and use it in GitHub Desktop.
class Job
def self.fetch
return new if rand(100) > 85 # only return a job 15% of the time
end
attr_reader :count
def initialize
@count = rand(5) # some random data
end
end
class Worker
def run
@starting = true
@terminating = false
@thread = Thread.new do
work(poll)
end
self
end
def join
return unless defined?(@thread)
@terminating = true
@thread.join
end
def starting?
@starting
end
def done?
defined?(@thread) && ! @thread.status
end
private
def poll
until @terminating || job = Job.fetch
sleep 0.25 # polling delay
end
job
end
def work(job)
@starting = false
job&.count&.times do
break if @terminating
sleep 0.25 # fake work
end
end
end
#
# The main body of script
#
Signal.trap("SIGINT") { throw :done }
MAX_WORKERS = 10
workers = []
catch :done do
loop do
workers.delete_if {|w| w.done? }
if workers.none?{|w| w.starting? } && workers.count < MAX_WORKERS
workers << Worker.new.run
end
sleep 0.25
end
end
workers.each(&:join)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment