56 lines
1.2 KiB
Ruby
56 lines
1.2 KiB
Ruby
module Mongo
|
|
module Async
|
|
|
|
class WorkerPool
|
|
attr_reader :workers
|
|
|
|
def initialize size
|
|
@jobs = Queue.new
|
|
@workers = Queue.new
|
|
|
|
@size = size
|
|
spawn_pool @size
|
|
end
|
|
|
|
def enqueue command, args, callback
|
|
# call compact to remove any nil arguments
|
|
@jobs << [command, args.compact, callback]
|
|
end
|
|
|
|
private
|
|
|
|
def spawn_pool size
|
|
size.times do
|
|
thread = Thread.new do
|
|
while true do
|
|
do_work
|
|
end
|
|
end
|
|
|
|
thread.abort_on_exception = true
|
|
@workers << thread
|
|
end
|
|
end
|
|
|
|
def do_work
|
|
# blocks on #pop until a job is available
|
|
command, cmd_args, callback = @jobs.pop
|
|
exception, result = nil, nil
|
|
|
|
# Call the original command with its arguments; capture
|
|
# and save any result and/or exception
|
|
begin
|
|
result = command.call *cmd_args
|
|
rescue => e
|
|
exception = e
|
|
end
|
|
|
|
# Execute the callback and pass in the exception and result;
|
|
# in successful cases, the exception should be nil
|
|
callback.call exception, result
|
|
end
|
|
end # Workers
|
|
|
|
end # Async
|
|
end # Mongo
|