Created
March 2, 2021 03:19
-
-
Save mgreenly/f8c01506c47968e7c7b445b773d92236 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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