Karousel is an intelligent, client-side job dispenser that accesses a parallelized service without overloading its queue. It dishes out jobs onto a defined number of 'seats' on the 'karousel', tosses out completed jobs, and refills empty 'seats' with new jobs. As a result, the queue on the parallelized service remains lean and clients make responsible use of the service.
The gem works on a carousel principle. Jobs are loaded onto a carousel-like object. The size of the 'karousel' (i.e. its 'seats') determines how many objects are active at any given time. For example, if the size of the 'karousel' is 20, only 20 objects at a time will access the service.
Karousel loads all jobs, initiates its rotation, and sends each job in succession to a service. For each new job, 'karousel' waits for an 'OK' from the service, captures the status of the job and optionally stores the response from the service. Starting with the oldest submitted job, 'karousel' checks to see if the job is finished. If it is finished, it is processed, removed from the 'karousel', and the seat is freed for a new job. After a rotation of the 'karousel' empty seats are filled with new jobs and the 'karousel' continues to rotate.
gem install karousel
Given a Karousel-compatible job class (e.g. KarouselJob) the usage is:
require 'karousel'
karousel = Karousel.new(KarouselJob, 20, 5)
karousel.run
where KarouselJob is the name of your job class, 20 is number of 'seats' on your 'karousel', and 5 is the time interval in seconds between complete rotations of the 'karousel'.
You can optionally supply a block to the 'run' method to perform your own logging, collect data, or other uses. For example:
count = 0
karousel.run { puts count += 1 }
or
result = []
karousel.run { result << karousel.cycle_data }
A Job class requires the following signature:
class MyJob < Karousel::ClientJob
def self.populate(number_of_seats)
... # returns an array of the karousel size
# (number_of_seats would be 20 in our example)
end
def send
... # sends the job to the service, returns true if it
# receives an expected response, false otherwise
end
def finished?
... # returns true if job is done, false otherwise
end
def process
... # processes the finished job
end
end
You can also check out an example file or example project
This gem is following practices of Semantic Versioning
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
Authors: Dmitry Mozzherin, David Shorthouse
Copyright (c) 2012-2013 Marine Biological Laboratory. See LICENSE for further details.