picky 3.1.8 → 3.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/picky/cores.rb +46 -26
  2. data/spec/lib/cores_spec.rb +104 -27
  3. 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 or generator.
9
+ # Pass it an ary.
10
10
  #
11
- # generator = (1..10).each
12
- # forked generator, :max => 5 do |element|
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 = max_processors options
33
- processing = 0
34
+ max = max_processors options
34
35
 
35
- loop do
36
- while processing < max
37
- # Get the next element
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
- # Fork and yield.
44
- #
45
- Process.fork do
46
- sleep 0.05*processing
47
- block.call element
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
- # Block and wait for any child to finish.
52
- #
53
- begin
54
- Process.wait 0
55
- rescue Errno::ECHILD => e
56
- break
57
- ensure
58
- processing -= 1
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
@@ -4,44 +4,121 @@ require 'spec_helper'
4
4
  describe Picky::Cores do
5
5
 
6
6
  describe ".forked" do
7
- before(:each) do
8
- Process.should_receive(:fork).any_number_of_times.and_yield
9
- end
10
- context "with array" do
11
- context "with block" do
12
- it "runs ok" do
13
- described_class.forked([1, 2]) do |e|
14
-
15
- end
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
- it "yields the elements" do
18
- result = []
19
- described_class.forked([1, 2]) do |e|
20
- result << e
21
- end
22
- result.should == [1, 2]
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
- context "without block" do
26
- it "fails" do
27
- lambda {
28
- described_class.forked [1, 2]
29
- }.should raise_error("Block argument needed when running Cores.forked")
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 "with empty array" do
34
- context "with block" do
35
- it "runs ok" do
36
- described_class.forked([]) do
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 "without block" do
42
- it "runs ok" do
43
- described_class.forked []
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.8
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.8
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.