Skip to content

Commit 5880ab9

Browse files
committed
Initial commit
0 parents  commit 5880ab9

18 files changed

+1125
-0
lines changed

.gitignore

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/vendor/
2+
/.bundle/
3+
/Gemfile.lock
4+
/.yardoc
5+
/.ruby-version
6+
.DS_Store
7+
coverage
8+
doc
9+
pkg
10+
*.swp
11+
*~

.rubocop.yml

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# This configuration was generated by
2+
# `rubocop --auto-gen-config`
3+
# on 2015-08-25 17:20:37 +0900 using RuboCop version 0.33.0.
4+
# The point is for the user to remove these configuration records
5+
# one by one as the offenses are removed from the code base.
6+
# Note that changes in the inspected code, or installation of new
7+
# versions of RuboCop, may require this file to be generated again.
8+
9+
AllCops:
10+
Exclude:
11+
- 'vendor/**/*'
12+
RunRailsCops: false
13+
DisplayCopNames: true
14+
15+
# Offense count: 1
16+
# Configuration parameters: AllowSafeAssignment.
17+
Lint/AssignmentInCondition:
18+
Enabled: false
19+
20+
# offense count: 1
21+
Lint/UselessAssignment:
22+
Exclude:
23+
- '*.gemspec'
24+
25+
# Offense count: 3
26+
Metrics/AbcSize:
27+
Exclude:
28+
- 'test/**/*'
29+
30+
# Offense count: 1
31+
# Configuration parameters: AllowURI, URISchemes.
32+
Metrics/LineLength:
33+
Exclude:
34+
- 'test/**/*'
35+
- '*.gemspec'
36+
37+
# Offense count: 8
38+
# Configuration parameters: CountComments.
39+
Metrics/MethodLength:
40+
Max: 128
41+
42+
# Offense count: 29
43+
# Cop supports --auto-correct.
44+
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
45+
Style/BlockDelimiters:
46+
Enabled: true
47+
EnforcedStyle: semantic
48+
Exclude:
49+
- 'test/**/*'
50+
51+
# Offense count: 1
52+
# Cop supports --auto-correct.
53+
# Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep.
54+
Style/CaseIndentation:
55+
Enabled: false
56+
57+
# Offense count: 2
58+
# Configuration parameters: EnforcedStyle, SupportedStyles.
59+
Style/ClassAndModuleChildren:
60+
Enabled: false
61+
62+
# Offense count: 1
63+
# Cop supports --auto-correct.
64+
# Configuration parameters: Keywords.
65+
Style/CommentAnnotation:
66+
Enabled: false
67+
68+
# Offense count: 4
69+
Style/Documentation:
70+
Exclude:
71+
- 'test/**/*'
72+
73+
# Offense count: 3
74+
# Cop supports --auto-correct.
75+
# Configuration parameters: EnforcedStyle, SupportedStyles.
76+
Style/EmptyLinesAroundClassBody:
77+
Enabled: false
78+
79+
# Offense count: 2
80+
# Cop supports --auto-correct.
81+
# Configuration parameters: AllowForAlignment.
82+
Style/ExtraSpacing:
83+
Enabled: false
84+
85+
# Offense count: 2
86+
# Cop supports --auto-correct.
87+
# Configuration parameters: Width.
88+
Style/IndentationWidth:
89+
Exclude:
90+
- 'lib/sized_parallel/pool.rb'
91+
92+
# Offense count: 1
93+
# Cop supports --auto-correct.
94+
Style/ElseAlignment:
95+
Exclude:
96+
- 'lib/sized_parallel/pool.rb'
97+
98+
# Offense count: 5
99+
# Cop supports --auto-correct.
100+
# Configuration parameters: EnforcedStyle, SupportedStyles.
101+
Style/MethodDefParentheses:
102+
Enabled: false
103+
104+
# Offense count: 5
105+
Style/MultilineBlockChain:
106+
Enabled: false
107+
108+
# Offense count: 1
109+
# Cop supports --auto-correct.
110+
Style/MultilineIfThen:
111+
Enabled: false
112+
113+
# Offense count: 3
114+
# Cop supports --auto-correct.
115+
# Configuration parameters: AllowMultipleReturnValues.
116+
Style/RedundantReturn:
117+
Enabled: false
118+
119+
# Offense count: 13
120+
# Cop supports --auto-correct.
121+
# Configuration parameters: EnforcedStyle, SupportedStyles.
122+
Style/SignalException:
123+
Enabled: false
124+
125+
# Offense count: 16
126+
# Cop supports --auto-correct.
127+
Style/SpaceInsideBrackets:
128+
Enabled: false
129+
130+
# Offense count: 9
131+
# Cop supports --auto-correct.
132+
# Configuration parameters: EnforcedStyle, SupportedStyles.
133+
Style/StringLiterals:
134+
Enabled: false
135+
136+
# Offense count: 1
137+
# Cop supports --auto-correct.
138+
Style/WhileUntilDo:
139+
Exclude:
140+
- 'lib/sized_parallel/pool.rb'

.yardopts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
--markup=markdown
2+
--charset utf-8
3+
--readme README.md
4+
lib/**/*.rb

Gemfile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#! /your/favourite/path/to/bundler
2+
# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level 2 -*-
3+
4+
# Copyright (c) 2015 Urabe, Shyouhei
5+
#
6+
# Permission is hereby granted, free of charge, to any person obtaining a copy
7+
# of this software and associated documentation files (the "Software"), to deal
8+
# in the Software without restriction, including without limitation the rights
9+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
# copies of the Software, and to permit persons to whom the Software is
11+
# furnished to do so, subject to the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be
14+
# included in all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
# SOFTWARE.
23+
24+
source 'https://rubygems.org'
25+
gemspec require: false

LICENSE.txt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2015 Urabe, Shyouhei
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of
4+
this software and associated documentation files (the "Software"), to deal in
5+
the Software without restriction, including without limitation the rights to
6+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7+
of the Software, and to permit persons to whom the Software is furnished to do
8+
so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be
11+
included in all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

README.md

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
This library lets you have a bunch of inter-dependent tasks run in parallel, but not all together. Much like `make -j4` runs at most 4 tasks at once.
2+
3+
### Detailed usage
4+
5+
This library has only one intuitive usage. First create a `SizedParallel` instance.
6+
7+
sp = SizedParallel.new 65535
8+
9+
Omit the argument to use the active CPU count (default).
10+
11+
Then add your series of jobs.
12+
13+
128.times {
14+
sp.start {
15+
Resolv.getaddress 'www.ruby-lang.org'
16+
}.then { |addr|
17+
Net::HTTP.get addr, '/'
18+
}.then { |html|
19+
Nokogiri::HTML html
20+
}
21+
}
22+
23+
In the example above 128 concurrent name resolution are registered. Then for each resolved address, HTTP query is registered (in parallel). And lastly the response HTML is registered to parse (also in parallel).
24+
25+
Those jobs are not triggered yet. In order to do so you call a wait for the object.
26+
27+
sp.wait
28+
29+
This blocks, until all the registered jobs finish either gracefully or unexpectedly.
30+
31+
### Restrictions
32+
33+
This library is written in pure ruby so ultra portable by nature, but requires at least version 2.2 or higher (or compatible alternatives) because Etc.nproessors is mandatory.

Rakefile

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#! /your/favourite/path/to/rake
2+
# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level 2 -*-
3+
4+
# Copyright (c) 2015 Urabe, Shyouhei
5+
#
6+
# Permission is hereby granted, free of charge, to any person obtaining a copy
7+
# of this software and associated documentation files (the "Software"), to deal
8+
# in the Software without restriction, including without limitation the rights
9+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
# copies of the Software, and to permit persons to whom the Software is
11+
# furnished to do so, subject to the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be
14+
# included in all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
# SOFTWARE.
23+
24+
require 'rubygems'
25+
require 'bundler/setup'
26+
Bundler.setup :development
27+
require 'rake'
28+
require 'yard'
29+
require 'bundler/gem_tasks'
30+
require 'rake/testtask'
31+
require 'rubocop/rake_task'
32+
33+
YARD::Rake::YardocTask.new
34+
RuboCop::RakeTask.new
35+
36+
task default: :test
37+
task spec: :test
38+
desc "run tests"
39+
Rake::TestTask.new do |t|
40+
t.test_files = FileList['test/**/*.rb'] - ['test/test_helper.rb']
41+
end
42+
43+
desc "a la rails console"
44+
task :console do
45+
require_relative 'lib/sized_parallel'
46+
require 'irb'
47+
require 'irb/completion'
48+
ARGV.clear
49+
IRB.start
50+
end
51+
task c: :console
52+
53+
desc "pry console"
54+
task :pry do
55+
require_relative 'lib/sized_parallel'
56+
require 'pry'
57+
ARGV.clear
58+
Pry.start
59+
end

lib/sized_parallel.rb

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#! /your/favourite/path/to/ruby
2+
# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level 2 -*-
3+
4+
# Copyright (c) 2015 Urabe, Shyouhei
5+
#
6+
# Permission is hereby granted, free of charge, to any person obtaining a copy
7+
# of this software and associated documentation files (the "Software"), to deal
8+
# in the Software without restriction, including without limitation the rights
9+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
# copies of the Software, and to permit persons to whom the Software is
11+
# furnished to do so, subject to the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be
14+
# included in all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
# SOFTWARE.
23+
24+
require 'etc'
25+
require 'thread'
26+
27+
# SizedParallel is a `make -j4` -like experience. When you do
28+
#
29+
# sp = SizedParallel.new
30+
# 1024.times do |i|
31+
# sp.start { printf("1: %d\n", i); sleep 1 }
32+
# .then { printf("2: %d\n", i); sleep 1 }
33+
# .then { printf("3: %d\n", i); sleep 1 }
34+
# end
35+
# sp.wait
36+
#
37+
# You see bunch of things run in parallel, but all the 2s are after
38+
# corresponding 1s, and 3s are after 2s.
39+
class SizedParallel
40+
41+
# Creates a set of execution. If a block is given, evaluates that block and
42+
# wait for self, i.e:
43+
#
44+
# SizedParallel.new do |sp|
45+
# ...
46+
# end
47+
#
48+
# is a shorthand for:
49+
#
50+
# sp = SizedParallel.new
51+
# begin
52+
# ...
53+
# ensure
54+
# sp.wait
55+
# end
56+
#
57+
# @param [Integer] n parallelizm.
58+
# @yieldparam [SizedParallel] self
59+
def initialize n = Etc.nprocessors
60+
if defined? yield then
61+
Pool.new n do |p|
62+
@p = p
63+
yield self
64+
end
65+
else
66+
@p = Pool.new n
67+
end
68+
end
69+
70+
# Starts a series of execution.
71+
# @note (see Pool#process)
72+
# @param (see Pool#process)
73+
# @yieldparam (see Pool#process)
74+
# @return [Task] a `then`-able.
75+
# @raise [ArgumentError] when no block is given.
76+
def start *argv
77+
raise ArgumentError, 'no block given' unless defined? yield
78+
Task.new @p do
79+
yield(*argv)
80+
end
81+
end
82+
83+
# Waits for tasks. It blocks until all the jobs are done.
84+
# @return [SizedParallel] self
85+
def wait
86+
@p.wait
87+
return self
88+
end
89+
end
90+
91+
require_relative 'sized_parallel/version'
92+
require_relative 'sized_parallel/pool'
93+
require_relative 'sized_parallel/task'

0 commit comments

Comments
 (0)