karousel 0.9.13 → 0.9.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +49 -0
- data/.ruby-version +1 -0
- data/.travis.yml +1 -1
- data/CHANGELOG +1 -0
- data/Gemfile +2 -3
- data/Gemfile.lock +19 -51
- data/README.md +129 -0
- data/Rakefile +9 -40
- data/bin/cdiff +16 -0
- data/bin/colortab +16 -0
- data/bin/coveralls +16 -0
- data/bin/decolor +16 -0
- data/bin/restclient +16 -0
- data/bin/term_display +16 -0
- data/bin/term_mandel +16 -0
- data/bin/thor +16 -0
- data/karousel.gemspec +16 -78
- data/lib/karousel.rb +5 -1
- data/lib/karousel/job.rb +4 -2
- data/lib/karousel/version.rb +3 -0
- data/spec/karousel_spec.rb +14 -0
- data/spec/spec_helper.rb +3 -0
- metadata +28 -78
- data/.rvmrc +0 -2
- data/README.rdoc +0 -79
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93a93eaf57fc60cc0adf49c6e327559f812d369a
|
4
|
+
data.tar.gz: f8ed2768ed3f5e4311112a7ff5217e49c85a3292
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae4345f80ae81991d61ef001665dff9691f94edc6fa2cb56230095d711dbf454ec3cedfa2b37973fd81b8864f8d38e45fea8659a2f2cb90ce81b8d36aca4f51f
|
7
|
+
data.tar.gz: baa91691ddd09c8a9f7b5313557a1f1a5fc295d8810cc1eb292947f15d605ded99e72f6f47d8099a29ebb04a6243ace38fc559b95eff1ea826c08ff2934e2b26
|
data/.gitignore
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# rcov generated
|
2
|
+
coverage
|
3
|
+
coverage.data
|
4
|
+
|
5
|
+
# rdoc generated
|
6
|
+
rdoc
|
7
|
+
|
8
|
+
# yard generated
|
9
|
+
doc
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# bundler
|
13
|
+
.bundle
|
14
|
+
|
15
|
+
# jeweler generated
|
16
|
+
pkg
|
17
|
+
|
18
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
19
|
+
#
|
20
|
+
# * Create a file at ~/.gitignore
|
21
|
+
# * Include files you want ignored
|
22
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
23
|
+
#
|
24
|
+
# After doing this, these files will be ignored in all your git projects,
|
25
|
+
# saving you from having to 'pollute' every project you touch with them
|
26
|
+
#
|
27
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
28
|
+
#
|
29
|
+
# For MacOS:
|
30
|
+
#
|
31
|
+
#.DS_Store
|
32
|
+
|
33
|
+
# For TextMate
|
34
|
+
#*.tmproj
|
35
|
+
#tmtags
|
36
|
+
|
37
|
+
# For emacs:
|
38
|
+
#*~
|
39
|
+
#\#*
|
40
|
+
#.\#*
|
41
|
+
|
42
|
+
# For vim:
|
43
|
+
#*.swp
|
44
|
+
|
45
|
+
# For redcar:
|
46
|
+
#.redcar
|
47
|
+
|
48
|
+
# For rubinius:
|
49
|
+
#*.rbc
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p247
|
data/.travis.yml
CHANGED
data/CHANGELOG
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
addressable (2.3.5)
|
5
|
-
builder (3.2.2)
|
6
4
|
columnize (0.3.6)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
coveralls (0.7.0)
|
6
|
+
multi_json (~> 1.3)
|
7
|
+
rest-client
|
8
|
+
simplecov (>= 0.7)
|
9
|
+
term-ansicolor
|
10
|
+
thor
|
13
11
|
debugger (1.6.1)
|
14
12
|
columnize (>= 0.3.1)
|
15
13
|
debugger-linecache (~> 1.2.0)
|
@@ -17,49 +15,11 @@ GEM
|
|
17
15
|
debugger-linecache (1.2.0)
|
18
16
|
debugger-ruby_core_source (1.2.3)
|
19
17
|
diff-lcs (1.2.4)
|
20
|
-
|
21
|
-
multipart-post (~> 1.2.0)
|
22
|
-
gherkin (2.12.1)
|
23
|
-
multi_json (~> 1.3)
|
24
|
-
git (1.2.6)
|
25
|
-
github_api (0.10.1)
|
26
|
-
addressable
|
27
|
-
faraday (~> 0.8.1)
|
28
|
-
hashie (>= 1.2)
|
29
|
-
multi_json (~> 1.4)
|
30
|
-
nokogiri (~> 1.5.2)
|
31
|
-
oauth2
|
32
|
-
hashie (2.0.5)
|
33
|
-
highline (1.6.19)
|
34
|
-
httpauth (0.2.0)
|
35
|
-
jeweler (1.8.7)
|
36
|
-
builder
|
37
|
-
bundler (~> 1.0)
|
38
|
-
git (>= 1.2.5)
|
39
|
-
github_api (= 0.10.1)
|
40
|
-
highline (>= 1.6.15)
|
41
|
-
nokogiri (= 1.5.10)
|
42
|
-
rake
|
43
|
-
rdoc
|
44
|
-
json (1.8.0)
|
45
|
-
jwt (0.1.8)
|
46
|
-
multi_json (>= 1.5)
|
18
|
+
mime-types (1.25)
|
47
19
|
multi_json (1.8.0)
|
48
|
-
multi_test (0.0.2)
|
49
|
-
multi_xml (0.5.5)
|
50
|
-
multipart-post (1.2.0)
|
51
|
-
nokogiri (1.5.10)
|
52
|
-
oauth2 (0.9.2)
|
53
|
-
faraday (~> 0.8)
|
54
|
-
httpauth (~> 0.2)
|
55
|
-
jwt (~> 0.1.4)
|
56
|
-
multi_json (~> 1.0)
|
57
|
-
multi_xml (~> 0.5)
|
58
|
-
rack (~> 1.2)
|
59
|
-
rack (1.5.2)
|
60
20
|
rake (10.1.0)
|
61
|
-
|
62
|
-
|
21
|
+
rest-client (1.6.7)
|
22
|
+
mime-types (>= 1.16)
|
63
23
|
rspec (2.14.1)
|
64
24
|
rspec-core (~> 2.14.0)
|
65
25
|
rspec-expectations (~> 2.14.0)
|
@@ -68,12 +28,20 @@ GEM
|
|
68
28
|
rspec-expectations (2.14.2)
|
69
29
|
diff-lcs (>= 1.1.3, < 2.0)
|
70
30
|
rspec-mocks (2.14.3)
|
31
|
+
simplecov (0.7.1)
|
32
|
+
multi_json (~> 1.0)
|
33
|
+
simplecov-html (~> 0.7.1)
|
34
|
+
simplecov-html (0.7.1)
|
35
|
+
term-ansicolor (1.2.2)
|
36
|
+
tins (~> 0.8)
|
37
|
+
thor (0.18.1)
|
38
|
+
tins (0.9.0)
|
71
39
|
|
72
40
|
PLATFORMS
|
73
41
|
ruby
|
74
42
|
|
75
43
|
DEPENDENCIES
|
76
|
-
|
44
|
+
coveralls (~> 0.7)
|
77
45
|
debugger (~> 1.6)
|
78
|
-
|
46
|
+
rake (~> 10.1)
|
79
47
|
rspec (~> 2.14)
|
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
Karousel
|
2
|
+
========
|
3
|
+
|
4
|
+
[![Gem Version][1]][2]
|
5
|
+
[![Continuous Integration Status][3]][4]
|
6
|
+
[![Coverage Status][5]][6]
|
7
|
+
[![CodePolice][7]][8]
|
8
|
+
[![Dependency Status][9]][10]
|
9
|
+
|
10
|
+
|
11
|
+
Karousel is an intelligent, client-side job dispenser that accesses a
|
12
|
+
parallelized service without overloading its queue. It dishes out jobs
|
13
|
+
onto a defined number of 'seats' on the 'karousel', tosses out completed
|
14
|
+
jobs, and refills empty 'seats' with new jobs. As a result, the queue on
|
15
|
+
the parallelized service remains lean and clients make responsible use
|
16
|
+
of the service.
|
17
|
+
|
18
|
+
Principle of operation
|
19
|
+
----------------------
|
20
|
+
|
21
|
+
The gem works on a carousel principle. Jobs are loaded onto a carousel-like
|
22
|
+
object. The size of the 'karousel' (i.e. its 'seats') determines how
|
23
|
+
many objects are active at any given time. For example, if the size of
|
24
|
+
the 'karousel' is 20, only 20 objects at a time will access the service.
|
25
|
+
|
26
|
+
Karousel loads all jobs, initiates its rotation, and sends each job in
|
27
|
+
succession to a service. For each new job, 'karousel' waits for an 'OK'
|
28
|
+
from the service, captures the status of the job and optionally stores the
|
29
|
+
response from the service. Starting with the oldest submitted job,
|
30
|
+
'karousel' checks to see if the job is finished. If it is finished, it is
|
31
|
+
processed, removed from the 'karousel', and the seat is freed for a new job.
|
32
|
+
After a rotation of the 'karousel' empty seats are filled with new jobs and
|
33
|
+
the 'karousel' continues to rotate.
|
34
|
+
|
35
|
+
Installation
|
36
|
+
------------
|
37
|
+
|
38
|
+
gem install karousel
|
39
|
+
|
40
|
+
Usage
|
41
|
+
-----
|
42
|
+
|
43
|
+
Given a Karousel-compatible job class (e.g. KarouselJob) the usage is:
|
44
|
+
|
45
|
+
require 'karousel'
|
46
|
+
karousel = Karousel.new(KarouselJob, 20, 5)
|
47
|
+
karousel.run
|
48
|
+
|
49
|
+
where KarouselJob is the name of your job class, 20 is number of 'seats'
|
50
|
+
on your 'karousel', and 5 is the time interval in seconds between complete
|
51
|
+
rotations of the 'karousel'.
|
52
|
+
|
53
|
+
You can optionally supply a block to the 'run' method to perform your own
|
54
|
+
logging, collect data, or other uses. For example:
|
55
|
+
|
56
|
+
count = 0
|
57
|
+
karousel.run { puts count += 1 }
|
58
|
+
|
59
|
+
or
|
60
|
+
|
61
|
+
result = []
|
62
|
+
karousel.run { result << karousel.cycle_data }
|
63
|
+
|
64
|
+
How to write a Job Class
|
65
|
+
------------------------
|
66
|
+
|
67
|
+
A Job class requires the following signature:
|
68
|
+
|
69
|
+
class MyJob < Karousel::ClientJob
|
70
|
+
|
71
|
+
def self.populate(number_of_seats)
|
72
|
+
... # returns an array of the karousel size
|
73
|
+
# (number_of_seats would be 20 in our example)
|
74
|
+
end
|
75
|
+
|
76
|
+
def send
|
77
|
+
... # sends the job to the service, returns true if it
|
78
|
+
# receives an expected response, false otherwise
|
79
|
+
end
|
80
|
+
|
81
|
+
def finished?
|
82
|
+
... # returns true if job is done, false otherwise
|
83
|
+
end
|
84
|
+
|
85
|
+
def process
|
86
|
+
... # processes the finished job
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
You can also check out an [example file][11] or [example project][12]
|
92
|
+
|
93
|
+
Versioning
|
94
|
+
----------
|
95
|
+
|
96
|
+
This gem is following practices of [Semantic Versioning][13]
|
97
|
+
|
98
|
+
Contributing
|
99
|
+
------------
|
100
|
+
|
101
|
+
1. Fork it
|
102
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
103
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
104
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
105
|
+
5. Create new Pull Request
|
106
|
+
|
107
|
+
Copyright
|
108
|
+
---------
|
109
|
+
|
110
|
+
Authors: [Dmitry Mozzherin][14], [David Shorthouse][15]
|
111
|
+
|
112
|
+
Copyright (c) 2012-2013 Marine Biological Laboratory. See LICENSE for
|
113
|
+
further details.
|
114
|
+
|
115
|
+
[1]: https://badge.fury.io/rb/karousel.png
|
116
|
+
[2]: http://badge.fury.io/rb/karousel
|
117
|
+
[3]: https://secure.travis-ci.org/GlobalNamesArchitecture/karousel.png
|
118
|
+
[4]: http://travis-ci.org/GlobalNamesArchitecture/karousel
|
119
|
+
[5]: https://coveralls.io/repos/GlobalNamesArchitecture/karousel/badge.png?branch=master
|
120
|
+
[6]: https://coveralls.io/r/GlobalNamesArchitecture/karousel?branch=master
|
121
|
+
[7]: https://codeclimate.com/github/GlobalNamesArchitecture/karousel.png
|
122
|
+
[8]: https://codeclimate.com/github/GlobalNamesArchitecture/karousel
|
123
|
+
[9]: https://gemnasium.com/GlobalNamesArchitecture/karousel.png
|
124
|
+
[10]: https://gemnasium.com/GlobalNamesArchitecture/karousel
|
125
|
+
[11]: https://github.com/GlobalNamesArchitecture/karousel/blob/master/spec/support/client_job_dummy.rb
|
126
|
+
[12]: https://github.com/GlobalNamesArchitecture/karousel
|
127
|
+
[13]: http://semver.org/
|
128
|
+
[14]: https://github.com/dimus
|
129
|
+
[15]: https://github.com/dshorthouse
|
data/Rakefile
CHANGED
@@ -1,52 +1,21 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
2
|
require 'bundler'
|
3
|
+
require 'rake'
|
4
|
+
require 'rspec/core'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
5
9
|
begin
|
6
10
|
Bundler.setup(:default, :development)
|
7
11
|
rescue Bundler::BundlerError => e
|
8
12
|
$stderr.puts e.message
|
9
|
-
$stderr.puts
|
13
|
+
$stderr.puts 'Run `bundle install` to install missing gems'
|
10
14
|
exit e.status_code
|
11
15
|
end
|
12
|
-
require 'rake'
|
13
|
-
|
14
|
-
require 'jeweler'
|
15
|
-
Jeweler::Tasks.new do |gem|
|
16
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
-
gem.name = "karousel"
|
18
|
-
gem.homepage = "http://github.com/GlobalNamesArchitecture/karousel"
|
19
|
-
gem.license = "MIT"
|
20
|
-
gem.summary = %Q{Job dispenser for parallel workers}
|
21
|
-
gem.description = %Q{Use it if you have waaay too many items in your workers' queue}
|
22
|
-
gem.email = "dmozzherin@gmail.com"
|
23
|
-
gem.authors = ["Dmitry Mozzherin", "David Shorthouse"]
|
24
|
-
# dependencies defined in Gemfile
|
25
|
-
end
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
27
|
-
|
28
|
-
require 'rspec/core'
|
29
|
-
require 'rspec/core/rake_task'
|
30
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
-
end
|
33
|
-
|
34
|
-
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
-
spec.rcov = true
|
37
|
-
end
|
38
|
-
|
39
|
-
require 'cucumber/rake/task'
|
40
|
-
Cucumber::Rake::Task.new(:features)
|
41
16
|
|
42
17
|
task :default => :spec
|
43
18
|
|
44
|
-
|
45
|
-
|
46
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
47
|
-
|
48
|
-
rdoc.rdoc_dir = 'rdoc'
|
49
|
-
rdoc.title = "karousel #{version}"
|
50
|
-
rdoc.rdoc_files.include('README*')
|
51
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
RSpec::Core::RakeTask.new do |t|
|
20
|
+
t.pattern = 'spec/**/*spec.rb'
|
52
21
|
end
|
data/bin/cdiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'cdiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('term-ansicolor', 'cdiff')
|
data/bin/colortab
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'colortab' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('term-ansicolor', 'colortab')
|
data/bin/coveralls
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'coveralls' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('coveralls', 'coveralls')
|
data/bin/decolor
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'decolor' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('term-ansicolor', 'decolor')
|
data/bin/restclient
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'restclient' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rest-client', 'restclient')
|
data/bin/term_display
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'term_display' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('term-ansicolor', 'term_display')
|
data/bin/term_mandel
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'term_mandel' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('term-ansicolor', 'term_mandel')
|
data/bin/thor
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'thor' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('thor', 'thor')
|
data/karousel.gemspec
CHANGED
@@ -1,84 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
-
# -*- encoding: utf-8 -*-
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
3
|
|
6
|
-
|
7
|
-
s.name = "karousel"
|
8
|
-
s.version = "0.9.13"
|
4
|
+
require 'karousel'
|
9
5
|
|
10
|
-
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
s.email =
|
15
|
-
s.
|
16
|
-
|
17
|
-
|
18
|
-
"README.rdoc"
|
19
|
-
]
|
20
|
-
s.files = [
|
21
|
-
".document",
|
22
|
-
".rspec",
|
23
|
-
".rvmrc",
|
24
|
-
".travis.yml",
|
25
|
-
"CHANGELOG",
|
26
|
-
"Gemfile",
|
27
|
-
"Gemfile.lock",
|
28
|
-
"LICENSE.txt",
|
29
|
-
"README.rdoc",
|
30
|
-
"Rakefile",
|
31
|
-
"VERSION",
|
32
|
-
"bin/autospec",
|
33
|
-
"bin/cucumber",
|
34
|
-
"bin/htmldiff",
|
35
|
-
"bin/jeweler",
|
36
|
-
"bin/ldiff",
|
37
|
-
"bin/nokogiri",
|
38
|
-
"bin/rackup",
|
39
|
-
"bin/rake",
|
40
|
-
"bin/rdebug",
|
41
|
-
"bin/ri",
|
42
|
-
"bin/rspec",
|
43
|
-
"features/karousel.feature",
|
44
|
-
"features/step_definitions/karousel_steps.rb",
|
45
|
-
"features/support/env.rb",
|
46
|
-
"karousel.gemspec",
|
47
|
-
"lib/karousel.rb",
|
48
|
-
"lib/karousel/client_job.rb",
|
49
|
-
"lib/karousel/errors.rb",
|
50
|
-
"lib/karousel/job.rb",
|
51
|
-
"spec/job_spec.rb",
|
52
|
-
"spec/karousel_spec.rb",
|
53
|
-
"spec/spec_helper.rb",
|
54
|
-
"spec/support/client_job_dummy.rb",
|
55
|
-
"spec/support/dummy_server.rb"
|
56
|
-
]
|
57
|
-
s.homepage = "http://github.com/GlobalNamesArchitecture/karousel"
|
58
|
-
s.licenses = ["MIT"]
|
59
|
-
s.require_paths = ["lib"]
|
60
|
-
s.rubygems_version = "2.0.3"
|
61
|
-
s.summary = "Job dispenser for parallel workers"
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'karousel'
|
8
|
+
s.version = Karousel::VERSION
|
9
|
+
s.authors = ['Dmitry Mozzherin', 'David Shorthouse']
|
10
|
+
s.email = 'dmozzherin@gmail.com'
|
11
|
+
s.description = %q{Use it if you have waaay too many items in
|
12
|
+
your workers' queue}
|
13
|
+
s.summary = 'Job dispenser for parallel workers'
|
62
14
|
|
63
|
-
|
64
|
-
|
15
|
+
s.homepage = 'http://github.com/GlobalNamesArchitecture/karousel'
|
16
|
+
s.license = 'MIT'
|
65
17
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.14"])
|
70
|
-
s.add_development_dependency(%q<debugger>, ["~> 1.6"])
|
71
|
-
else
|
72
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
73
|
-
s.add_dependency(%q<cucumber>, ["~> 1.3"])
|
74
|
-
s.add_dependency(%q<rspec>, ["~> 2.14"])
|
75
|
-
s.add_dependency(%q<debugger>, ["~> 1.6"])
|
76
|
-
end
|
77
|
-
else
|
78
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
79
|
-
s.add_dependency(%q<cucumber>, ["~> 1.3"])
|
80
|
-
s.add_dependency(%q<rspec>, ["~> 2.14"])
|
81
|
-
s.add_dependency(%q<debugger>, ["~> 1.6"])
|
82
|
-
end
|
18
|
+
s.files = `git ls-files`.split($/)
|
19
|
+
s.test_files = s.files.grep(%r{^(spec|features)/})
|
20
|
+
s.require_paths = ['lib']
|
83
21
|
end
|
84
22
|
|
data/lib/karousel.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
Dir[File.join(File.dirname(__FILE__),
|
1
|
+
Dir[File.join(File.dirname(__FILE__), 'karousel', '*.rb')].each {|f| require f}
|
2
2
|
|
3
3
|
|
4
4
|
class Karousel
|
5
5
|
attr_reader :size, :seats, :time_interval
|
6
6
|
STATUS = { init: 1, sent: 2, success: 3, failure: 4 }
|
7
7
|
|
8
|
+
def self.version
|
9
|
+
VERSION
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize(klass, size=10, time_interval = 0)
|
9
13
|
@klass = klass
|
10
14
|
@size = size
|
data/lib/karousel/job.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
class Karousel
|
2
2
|
class Job
|
3
3
|
attr_reader :client_job
|
4
|
-
STATUS = { init: 1, sent: 2, success: 3, failure: 4 }
|
4
|
+
# STATUS = { init: 1, sent: 2, success: 3, failure: 4 }
|
5
5
|
|
6
6
|
def initialize(client_job)
|
7
|
-
|
7
|
+
unless client_job.is_a?(Karousel::ClientJob)
|
8
|
+
raise TypeError.new('Unknown client job type')
|
9
|
+
end
|
8
10
|
@client_job = client_job
|
9
11
|
end
|
10
12
|
|
data/spec/karousel_spec.rb
CHANGED
@@ -8,6 +8,10 @@ describe "Karousel" do
|
|
8
8
|
before(:each) do
|
9
9
|
ClientJobDummy.reset
|
10
10
|
end
|
11
|
+
|
12
|
+
it 'should have version' do
|
13
|
+
Karousel.version.should =~ /^[\d]+\.[\d]+\.[\d]+$/
|
14
|
+
end
|
11
15
|
|
12
16
|
it "should initiate" do
|
13
17
|
k = Karousel.new(ClientJobDummy, 20, 0)
|
@@ -22,6 +26,14 @@ describe "Karousel" do
|
|
22
26
|
|
23
27
|
it "should run with block" do
|
24
28
|
karousel = Karousel.new(ClientJobDummy, 20, 0)
|
29
|
+
count = 0
|
30
|
+
karousel.run do
|
31
|
+
count += 1
|
32
|
+
if count < 10
|
33
|
+
karousel.seats[1].class.should == Karousel::Job
|
34
|
+
karousel.seats[1].client_job.class.should == ClientJobDummy
|
35
|
+
end
|
36
|
+
end
|
25
37
|
end
|
26
38
|
|
27
39
|
it "should be able to get loaded with jobs" do
|
@@ -32,4 +44,6 @@ describe "Karousel" do
|
|
32
44
|
@karousel.seats[0].status.should == Karousel::STATUS[:init]
|
33
45
|
end
|
34
46
|
|
47
|
+
|
48
|
+
|
35
49
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: karousel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitry Mozzherin
|
@@ -9,96 +9,33 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
13
|
-
dependencies:
|
14
|
-
|
15
|
-
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
requirements:
|
18
|
-
- - ~>
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: '1.8'
|
21
|
-
type: :runtime
|
22
|
-
prerelease: false
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - ~>
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '1.8'
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: cucumber
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
31
|
-
requirements:
|
32
|
-
- - ~>
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version: '1.3'
|
35
|
-
type: :development
|
36
|
-
prerelease: false
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - ~>
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: '1.3'
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: rspec
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - ~>
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '2.14'
|
49
|
-
type: :development
|
50
|
-
prerelease: false
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - ~>
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '2.14'
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: debugger
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
59
|
-
requirements:
|
60
|
-
- - ~>
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '1.6'
|
63
|
-
type: :development
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ~>
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '1.6'
|
70
|
-
description: Use it if you have waaay too many items in your workers' queue
|
12
|
+
date: 2013-09-19 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: "Use it if you have waaay too many items in \n your
|
15
|
+
workers' queue"
|
71
16
|
email: dmozzherin@gmail.com
|
72
|
-
executables:
|
73
|
-
- autospec
|
74
|
-
- cucumber
|
75
|
-
- htmldiff
|
76
|
-
- jeweler
|
77
|
-
- ldiff
|
78
|
-
- nokogiri
|
79
|
-
- rackup
|
80
|
-
- rake
|
81
|
-
- rdebug
|
82
|
-
- ri
|
83
|
-
- rspec
|
17
|
+
executables: []
|
84
18
|
extensions: []
|
85
|
-
extra_rdoc_files:
|
86
|
-
- LICENSE.txt
|
87
|
-
- README.rdoc
|
19
|
+
extra_rdoc_files: []
|
88
20
|
files:
|
89
21
|
- .document
|
22
|
+
- .gitignore
|
90
23
|
- .rspec
|
91
|
-
- .
|
24
|
+
- .ruby-version
|
92
25
|
- .travis.yml
|
93
26
|
- CHANGELOG
|
94
27
|
- Gemfile
|
95
28
|
- Gemfile.lock
|
96
29
|
- LICENSE.txt
|
97
|
-
- README.
|
30
|
+
- README.md
|
98
31
|
- Rakefile
|
99
32
|
- VERSION
|
100
33
|
- bin/autospec
|
34
|
+
- bin/cdiff
|
35
|
+
- bin/colortab
|
36
|
+
- bin/coveralls
|
101
37
|
- bin/cucumber
|
38
|
+
- bin/decolor
|
102
39
|
- bin/htmldiff
|
103
40
|
- bin/jeweler
|
104
41
|
- bin/ldiff
|
@@ -106,8 +43,12 @@ files:
|
|
106
43
|
- bin/rackup
|
107
44
|
- bin/rake
|
108
45
|
- bin/rdebug
|
46
|
+
- bin/restclient
|
109
47
|
- bin/ri
|
110
48
|
- bin/rspec
|
49
|
+
- bin/term_display
|
50
|
+
- bin/term_mandel
|
51
|
+
- bin/thor
|
111
52
|
- features/karousel.feature
|
112
53
|
- features/step_definitions/karousel_steps.rb
|
113
54
|
- features/support/env.rb
|
@@ -116,6 +57,7 @@ files:
|
|
116
57
|
- lib/karousel/client_job.rb
|
117
58
|
- lib/karousel/errors.rb
|
118
59
|
- lib/karousel/job.rb
|
60
|
+
- lib/karousel/version.rb
|
119
61
|
- spec/job_spec.rb
|
120
62
|
- spec/karousel_spec.rb
|
121
63
|
- spec/spec_helper.rb
|
@@ -145,4 +87,12 @@ rubygems_version: 2.0.3
|
|
145
87
|
signing_key:
|
146
88
|
specification_version: 4
|
147
89
|
summary: Job dispenser for parallel workers
|
148
|
-
test_files:
|
90
|
+
test_files:
|
91
|
+
- features/karousel.feature
|
92
|
+
- features/step_definitions/karousel_steps.rb
|
93
|
+
- features/support/env.rb
|
94
|
+
- spec/job_spec.rb
|
95
|
+
- spec/karousel_spec.rb
|
96
|
+
- spec/spec_helper.rb
|
97
|
+
- spec/support/client_job_dummy.rb
|
98
|
+
- spec/support/dummy_server.rb
|
data/.rvmrc
DELETED
data/README.rdoc
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
= Karousel
|
2
|
-
|
3
|
-
{<img src="https://secure.travis-ci.org/GlobalNamesArchitecture/karousel.png" />}[http://travis-ci.org/GlobalNamesArchitecture/karousel] {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/GlobalNamesArchitecture/karousel]
|
4
|
-
|
5
|
-
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.
|
6
|
-
|
7
|
-
== Principle of operation
|
8
|
-
|
9
|
-
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.
|
10
|
-
|
11
|
-
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.
|
12
|
-
|
13
|
-
== Installation
|
14
|
-
|
15
|
-
gem install karousel
|
16
|
-
|
17
|
-
== Usage
|
18
|
-
|
19
|
-
Given a Karousel-compatible job class (e.g. KarouselJob) the usage is:
|
20
|
-
|
21
|
-
require 'karousel'
|
22
|
-
karousel = Karousel.new(KarouselJob, 20, 5)
|
23
|
-
karousel.run
|
24
|
-
|
25
|
-
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'.
|
26
|
-
|
27
|
-
You can optionally supply a block to the 'run' method to perform your own logging, collect data, or other uses. For example:
|
28
|
-
|
29
|
-
count = 0
|
30
|
-
karousel.run { puts count += 1 }
|
31
|
-
|
32
|
-
or
|
33
|
-
|
34
|
-
result = []
|
35
|
-
karousel.run { result << karousel.cycle_data }
|
36
|
-
|
37
|
-
== How to write a Job Class
|
38
|
-
|
39
|
-
A Job class requires the following signature:
|
40
|
-
|
41
|
-
class MyJob < Karousel::ClientJob
|
42
|
-
|
43
|
-
def self.populate(number_of_seats)
|
44
|
-
... #returns an array of the karousel size (number_of_seats would be 20 in our example)
|
45
|
-
end
|
46
|
-
|
47
|
-
def send
|
48
|
-
... #sends the job to the service, returns true if it receives an expected response, false otherwise
|
49
|
-
end
|
50
|
-
|
51
|
-
def finished?
|
52
|
-
... #returns true if job is done, false otherwise
|
53
|
-
end
|
54
|
-
|
55
|
-
def process
|
56
|
-
... #processes the finished job
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
You can also check out https://github.com/GlobalNamesArchitecture/karousel/blob/master/spec/support/client_job_dummy.rb file or https://github.com/GlobalNamesArchitecture/karousel_example
|
62
|
-
|
63
|
-
== Contributing to karousel
|
64
|
-
|
65
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't yet been fixed.
|
66
|
-
* Check out the issue tracker to make sure someone hasn't already submitted a similar request and/or a solution.
|
67
|
-
* Fork the project.
|
68
|
-
* Start a feature/bugfix branch.
|
69
|
-
* Commit and push until you are happy with your contribution.
|
70
|
-
* Make sure you add tests. This is important so I don't unintentionally break Karousel in the future.
|
71
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, that's fine, but please isolate to its commit so I can cherry-pick around it.
|
72
|
-
|
73
|
-
== Copyright
|
74
|
-
|
75
|
-
Authors: Dmitry Mozzherin, David Shorthouse
|
76
|
-
|
77
|
-
Copyright (c) 2012 Marine Biological Laboratory. See LICENSE.txt for
|
78
|
-
further details.
|
79
|
-
|