picky 3.1.8 → 3.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/picky/cores.rb +46 -26
- data/spec/lib/cores_spec.rb +104 -27
- metadata +2 -2
data/lib/picky/cores.rb
CHANGED
@@ -6,15 +6,17 @@ module Picky
|
|
6
6
|
#
|
7
7
|
class Cores # :nodoc:all
|
8
8
|
|
9
|
-
# Pass it an ary
|
9
|
+
# Pass it an ary.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
# forked
|
11
|
+
# ary = (1..10).to_a
|
12
|
+
# forked ary, :max => 5 do |element|
|
13
13
|
#
|
14
14
|
# end
|
15
15
|
#
|
16
16
|
# Options include:
|
17
17
|
# * max: Maximum # of processors to use. Default is all it can get.
|
18
|
+
# * amount: An exactly defined amount of processors to use.
|
19
|
+
# * randomly: Whether to use random order or not.
|
18
20
|
#
|
19
21
|
def self.forked elements, options = {}, &block
|
20
22
|
return if elements.empty?
|
@@ -29,40 +31,58 @@ module Picky
|
|
29
31
|
|
30
32
|
# Get the maximum number of processors.
|
31
33
|
#
|
32
|
-
max
|
33
|
-
processing = 0
|
34
|
+
max = max_processors options
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
element = elements.shift
|
40
|
-
break unless element
|
41
|
-
processing += 1
|
36
|
+
# Decide whether to use forking.
|
37
|
+
#
|
38
|
+
if fork?(max)
|
39
|
+
processing = 0
|
42
40
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
loop do
|
42
|
+
while processing < max
|
43
|
+
# Get the next element
|
44
|
+
#
|
45
|
+
element = elements.shift
|
46
|
+
break unless element
|
47
|
+
processing += 1
|
48
|
+
|
49
|
+
# Fork and yield.
|
50
|
+
#
|
51
|
+
Process.fork do
|
52
|
+
sleep 0.05*processing
|
53
|
+
block.call element
|
54
|
+
end
|
48
55
|
end
|
49
|
-
end
|
50
56
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
# Block and wait for any child to finish.
|
58
|
+
#
|
59
|
+
begin
|
60
|
+
Process.wait 0
|
61
|
+
rescue Errno::ECHILD => e
|
62
|
+
break
|
63
|
+
ensure
|
64
|
+
processing -= 1
|
65
|
+
end
|
59
66
|
end
|
67
|
+
else
|
68
|
+
elements.each &block
|
60
69
|
end
|
61
70
|
|
62
71
|
end
|
63
72
|
|
73
|
+
# Do not fork if there is just one processor,
|
74
|
+
# or as in Windows, if there isn't the
|
75
|
+
# possibility of forking.
|
76
|
+
#
|
77
|
+
def self.fork? max_processors
|
78
|
+
max_processors > 1 && Process.respond_to?(:fork)
|
79
|
+
end
|
80
|
+
|
64
81
|
# Return the number of maximum usable processors.
|
65
82
|
#
|
83
|
+
# Options
|
84
|
+
# max: The maximum amount of cores used.
|
85
|
+
#
|
66
86
|
def self.max_processors options = {}
|
67
87
|
options[:amount] || [number_of_cores, (options[:max] || Infinity)].min
|
68
88
|
end
|
data/spec/lib/cores_spec.rb
CHANGED
@@ -4,44 +4,121 @@ require 'spec_helper'
|
|
4
4
|
describe Picky::Cores do
|
5
5
|
|
6
6
|
describe ".forked" do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
context 'without fork' do
|
8
|
+
before(:each) do
|
9
|
+
Picky::Cores.stub! :fork? => false
|
10
|
+
end
|
11
|
+
it 'should not fork' do
|
12
|
+
Process.should_receive(:fork).never
|
13
|
+
|
14
|
+
described_class.forked([1,2]) do |element|
|
15
|
+
|
16
16
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
result
|
17
|
+
end
|
18
|
+
it 'should yield the two elements' do
|
19
|
+
result = []
|
20
|
+
|
21
|
+
described_class.forked([1,2]) do |element|
|
22
|
+
result << element
|
23
23
|
end
|
24
|
+
|
25
|
+
result.should == [1,2]
|
24
26
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
it 'should yield the two elements' do
|
28
|
+
result = []
|
29
|
+
|
30
|
+
described_class.forked([1,2], randomly: true) do |element|
|
31
|
+
result << element
|
32
|
+
end
|
33
|
+
|
34
|
+
# This test remains like this because I
|
35
|
+
# like the stupidity of it.
|
36
|
+
#
|
37
|
+
if result == [1,2]
|
38
|
+
result.should == [1,2]
|
39
|
+
else
|
40
|
+
result.should == [2,1]
|
30
41
|
end
|
31
42
|
end
|
32
43
|
end
|
33
|
-
context
|
34
|
-
|
35
|
-
|
36
|
-
|
44
|
+
context 'with forking' do
|
45
|
+
before(:each) do
|
46
|
+
Picky::Cores.stub! :fork? => true
|
47
|
+
Process.should_receive(:fork).any_number_of_times.and_yield
|
48
|
+
end
|
49
|
+
context "with array" do
|
50
|
+
context "with block" do
|
51
|
+
it "runs ok" do
|
52
|
+
# TODO Problematic test. Should not raise the first time
|
53
|
+
#
|
54
|
+
Process.should_receive(:wait).once.and_raise Errno::ECHILD.new
|
55
|
+
|
56
|
+
described_class.forked([1, 2]) do |e|
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
it "yields the elements" do
|
61
|
+
result = []
|
62
|
+
|
63
|
+
described_class.forked([1, 2]) do |e|
|
64
|
+
result << e
|
65
|
+
end
|
37
66
|
|
67
|
+
result.should == [1, 2]
|
68
|
+
end
|
69
|
+
it 'should not fork with amount option' do
|
70
|
+
Process.should_receive(:fork).never
|
71
|
+
|
72
|
+
described_class.forked([1,2], amount: 1) do |element|
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
it 'should not fork with max == 1 option' do
|
77
|
+
Process.should_receive(:fork).never
|
78
|
+
|
79
|
+
described_class.forked([1,2], max: 1) do |element|
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
context "without block" do
|
85
|
+
it "fails" do
|
86
|
+
lambda {
|
87
|
+
described_class.forked [1, 2]
|
88
|
+
}.should raise_error("Block argument needed when running Cores.forked")
|
38
89
|
end
|
39
90
|
end
|
40
91
|
end
|
41
|
-
context "
|
42
|
-
|
43
|
-
|
92
|
+
context "with empty array" do
|
93
|
+
context "with block" do
|
94
|
+
it "runs ok" do
|
95
|
+
described_class.forked([]) do
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
44
99
|
end
|
100
|
+
context "without block" do
|
101
|
+
it "runs ok" do
|
102
|
+
described_class.forked []
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'fork?' do
|
110
|
+
context 'with forking capabilities' do
|
111
|
+
before(:all) do
|
112
|
+
# Process.should_receive(:respond_to?).any_number_of_times.with(:fork).and_return true
|
113
|
+
end
|
114
|
+
it 'returns false' do
|
115
|
+
Picky::Cores.fork?(0).should == false
|
116
|
+
end
|
117
|
+
it 'returns false' do
|
118
|
+
Picky::Cores.fork?(1).should == false
|
119
|
+
end
|
120
|
+
it 'returns true' do
|
121
|
+
Picky::Cores.fork?(2).should == true
|
45
122
|
end
|
46
123
|
end
|
47
124
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: picky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 3.1.
|
5
|
+
version: 3.1.9
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Florian Hanke
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 3.1.
|
35
|
+
version: 3.1.9
|
36
36
|
type: :development
|
37
37
|
version_requirements: *id002
|
38
38
|
description: Fast Ruby semantic text search engine with comfortable single field interface.
|