multi_process 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 731c2378d159300a61fd6a9f23dddd45622796e1
4
- data.tar.gz: f2566050f932d6ab956546488f4e71c809309300
3
+ metadata.gz: 12b6e61ecec6390d6c06f1ddbdc1a9288f65c0c1
4
+ data.tar.gz: b09e0b1587f578428daa05bb4dacb1fe11324dc9
5
5
  SHA512:
6
- metadata.gz: 5caec6a0db5b55c9f15a54d2ffe90c1193788b143294f6055b066a8b8df2686b4f2abd5c5e02639540f9b30e5a70e8297f49348e6b2c43d615deed5dc41c8356
7
- data.tar.gz: 532cded7fcbc61978623ddf44527db3060812e91896081d78b294e2f1749ff7f46c571b14af4e8896bf76dbfe77f7754999c6194722f0b323e65504c492c02e0
6
+ metadata.gz: 8e3e41b5665d57220412d203735786c7ae506386824cd3c6b00830692414c81e7dfdf4d697321ebffccb7d420e661018e45efe19e94712ceaad91bd38a8d7ef7
7
+ data.tar.gz: c57700b68cc35c3a5f63268d70ed10a89d04069e7e87f08418c8513e30c9571716b1a53699713cd83ee61846030997e2547251ab05b93b5ebf6814641fbe561c
@@ -13,6 +13,9 @@ module MultiProcess
13
13
  #
14
14
  attr_accessor :receiver
15
15
 
16
+ # Partition size.
17
+ attr_reader :partition
18
+
16
19
  # Create new process group.
17
20
  #
18
21
  # @param opts [ Hash ] Options
@@ -22,6 +25,8 @@ module MultiProcess
22
25
  def initialize(opts = {})
23
26
  @processes = []
24
27
  @receiver = opts[:receiver] ? opts[:receiver] : MultiProcess::Logger.global
28
+ @partition = opts[:partition] ? opts[:partition].to_i : 0
29
+ @mutex = Mutex.new
25
30
  end
26
31
 
27
32
  # Add new process or list of processes.
@@ -33,7 +38,7 @@ module MultiProcess
33
38
  def <<(process)
34
39
  Array(process).flatten.each do |process|
35
40
  processes << process
36
- # process.receiver = receiver
41
+ process.receiver = receiver
37
42
 
38
43
  if started?
39
44
  start process
@@ -89,14 +94,27 @@ module MultiProcess
89
94
 
90
95
  # Start all process and wait for them to terminate.
91
96
  #
92
- # Given options will be passed to {#wait}.
97
+ # Given options will be passed to {#start} and {#wait}.
98
+ # {#start} will only be called if partition is zero.
93
99
  #
94
100
  # If timeout is given process will be terminated using {#stop}
95
101
  # when timeout error is raised.
96
102
  #
97
103
  def run(opts = {})
98
- start
99
- wait opts
104
+ if partition > 0
105
+ threads = Array.new
106
+ partition.times do
107
+ threads << Thread.new do
108
+ while (process = next_process)
109
+ process.run
110
+ end
111
+ end
112
+ end
113
+ threads.each &:join
114
+ else
115
+ start opts
116
+ wait opts
117
+ end
100
118
  ensure
101
119
  stop
102
120
  end
@@ -132,5 +150,14 @@ module MultiProcess
132
150
  processes.each{|p| p.available! }
133
151
  end
134
152
  end
153
+
154
+ private
155
+ def next_process
156
+ @mutex.synchronize do
157
+ @index ||= 0
158
+ @index += 1
159
+ processes[@index - 1]
160
+ end
161
+ end
135
162
  end
136
163
  end
@@ -30,7 +30,7 @@ module MultiProcess
30
30
  when :out, :stdout
31
31
  output process, line
32
32
  when :sys
33
- output(process, line, delimiter: '$>')# if @opts[:sys]
33
+ output(process, line, delimiter: '$>') if @opts[:sys]
34
34
  end
35
35
  end
36
36
 
@@ -187,13 +187,12 @@ module MultiProcess
187
187
  #
188
188
  def start_childprocess
189
189
  env.each{|k, v| childprocess.environment[k.to_s] = v.to_s }
190
+ childprocess.cwd = dir
190
191
 
191
- Dir.chdir(dir) do
192
- if clean_env?
193
- Bundler.with_clean_env { childprocess.start }
194
- else
195
- childprocess.start
196
- end
192
+ if clean_env?
193
+ Bundler.with_clean_env { childprocess.start }
194
+ else
195
+ childprocess.start
197
196
  end
198
197
  end
199
198
  end
@@ -1,7 +1,7 @@
1
1
  module MultiProcess
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 1
4
+ MINOR = 2
5
5
  PATCH = 0
6
6
  STAGE = nil
7
7
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
data/spec/files/test.rb CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  2.times do
3
- $stdout.print "Output from #{ARGV[0]}"
3
+ $stdout.puts "Output from #{ARGV[0]}"
4
4
  $stdout.flush
5
5
  sleep rand
6
6
  end
@@ -6,26 +6,26 @@ describe MultiProcess do
6
6
  reader, writer = IO.pipe
7
7
 
8
8
  logger = MultiProcess::Logger.new writer
9
- group = MultiProcess::Group.new #receiver: logger
9
+ group = MultiProcess::Group.new receiver: logger
10
10
  group << MultiProcess::Process.new(%w(ruby spec/files/test.rb A), title: 'rubyA')
11
11
  group << MultiProcess::Process.new(%w(ruby spec/files/test.rb B), title: 'rubyB')
12
12
  group << MultiProcess::Process.new(%w(ruby spec/files/test.rb C), title: 'rubyC')
13
13
  group.run
14
14
 
15
15
  expect(reader.read_nonblock(4096).split("\n")).to match_array <<-EOF.gsub(/^\s+/, ' ').split("\n")
16
- rubyB | Output from B
17
- rubyA | Output from A
18
- rubyA | Output from A
19
- rubyC | Output from C
20
- rubyC | Output from C
21
- rubyB | Output from B
16
+ rubyB | Output from B
17
+ rubyA | Output from A
18
+ rubyA | Output from A
19
+ rubyC | Output from C
20
+ rubyC | Output from C
21
+ rubyB | Output from B
22
22
  EOF
23
23
  end
24
24
 
25
25
  it 'should run processes' do
26
26
  start = Time.now
27
27
 
28
- group = MultiProcess::Group.new# logger: MultiProcess::NilReceiver.new
28
+ group = MultiProcess::Group.new receiver: MultiProcess::NilReceiver.new
29
29
  group << MultiProcess::Process.new(%w(ruby spec/files/sleep.rb 5000), title: 'rubyA')
30
30
  group << MultiProcess::Process.new(%w(ruby spec/files/sleep.rb 5000), title: 'rubyB')
31
31
  group << MultiProcess::Process.new(%w(ruby spec/files/sleep.rb 5000), title: 'rubyC')
@@ -38,4 +38,20 @@ describe MultiProcess do
38
38
  end
39
39
  expect(Time.now - start).to be < 2
40
40
  end
41
+
42
+ it 'should partition processes' do
43
+ group = MultiProcess::Group.new partition: 4, receiver: MultiProcess::NilReceiver.new
44
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyA')
45
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyB')
46
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyC')
47
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyD')
48
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyE')
49
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyF')
50
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyG')
51
+ group << MultiProcess::Process.new(%w(ruby sleep.rb 1), dir: 'spec/files', title: 'rubyH')
52
+
53
+ start = Time.now
54
+ group.run
55
+ expect(Time.now - start).to be_within(0.3).of(2)
56
+ end
41
57
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_process
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen