parallel 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parallel (0.6.5)
4
+ parallel (0.7.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/Readme.md CHANGED
@@ -78,7 +78,7 @@ gem install ruby-progressbar
78
78
  ```Ruby
79
79
  require 'ruby-progressbar'
80
80
  progress = ProgressBar.create(:title => "The Progress", :total => 100)
81
- Parallel.map(1..100, :finish => lambda { |i, item| progress.increment }) { sleep 1 }
81
+ Parallel.map(1..100, :finish => lambda { |item, i| progress.increment }) { sleep 1 }
82
82
  ```
83
83
 
84
84
  Tips
@@ -66,7 +66,7 @@ module Parallel
66
66
  end
67
67
  end
68
68
 
69
- wait_for_threads(threads)
69
+ kill_on_ctrl_c(threads) { wait_for_threads(threads) }
70
70
 
71
71
  out
72
72
  end
@@ -196,29 +196,30 @@ module Parallel
196
196
  current_index = -1
197
197
  results = []
198
198
  exception = nil
199
+ kill_on_ctrl_c(workers.map(&:pid)) do
200
+ in_threads(options[:count]) do |i|
201
+ worker = workers[i]
199
202
 
200
- in_threads(options[:count]) do |i|
201
- worker = workers[i]
202
-
203
- begin
204
- loop do
205
- break if exception
206
- index = Thread.exclusive{ current_index += 1 }
207
- break if index >= items.size
208
-
209
- output = with_instrumentation items[index], index, options do
210
- worker.work(index)
211
- end
212
-
213
- if ExceptionWrapper === output
214
- exception = output.exception
215
- else
216
- results[index] = output
203
+ begin
204
+ loop do
205
+ break if exception
206
+ index = Thread.exclusive{ current_index += 1 }
207
+ break if index >= items.size
208
+
209
+ output = with_instrumentation items[index], index, options do
210
+ worker.work(index)
211
+ end
212
+
213
+ if ExceptionWrapper === output
214
+ exception = output.exception
215
+ else
216
+ results[index] = output
217
+ end
217
218
  end
219
+ ensure
220
+ worker.close_pipes
221
+ worker.wait # if it goes zombie, rather wait here to be able to debug
218
222
  end
219
- ensure
220
- worker.close_pipes
221
- worker.wait # if it goes zombie, rather wait here to be able to debug
222
223
  end
223
224
  end
224
225
 
@@ -230,8 +231,6 @@ module Parallel
230
231
  Array.new(options[:count]).each do
231
232
  workers << worker(items, options.merge(:started_workers => workers), &block)
232
233
  end
233
-
234
- kill_on_ctrl_c(workers.map(&:pid))
235
234
  workers
236
235
  end
237
236
 
@@ -302,19 +301,35 @@ module Parallel
302
301
  [count, options]
303
302
  end
304
303
 
305
- # kill all these processes (children) if user presses Ctrl+c
306
- def kill_on_ctrl_c(pids)
307
- Signal.trap :SIGINT do
308
- $stderr.puts 'Parallel execution interrupted, exiting ...'
309
- pids.compact.each do |pid|
310
- begin
311
- Process.kill(:KILL, pid)
312
- rescue Errno::ESRCH
313
- # some linux systems already automatically killed the children at this point
314
- # so we just ignore them not being there
304
+ # kill all these pids or threads if user presses Ctrl+c
305
+ def kill_on_ctrl_c(things)
306
+ if @to_be_killed
307
+ @to_be_killed << things
308
+ else
309
+ @to_be_killed = [things]
310
+ Signal.trap :SIGINT do
311
+ if @to_be_killed.any?
312
+ $stderr.puts 'Parallel execution interrupted, exiting ...'
313
+ @to_be_killed.flatten.compact.each { |thing| kill_that_thing!(thing) }
315
314
  end
315
+ exit 1 # Quit with 'failed' signal
316
+ end
317
+ end
318
+ yield
319
+ ensure
320
+ @to_be_killed.pop # free threads for GC and do not kill pids that could be used for new processes
321
+ end
322
+
323
+ def kill_that_thing!(thing)
324
+ if thing.is_a?(Thread)
325
+ thing.kill
326
+ else
327
+ begin
328
+ Process.kill(:KILL, thing)
329
+ rescue Errno::ESRCH
330
+ # some linux systems already automatically killed the children at this point
331
+ # so we just ignore them not being there
316
332
  end
317
- exit 1 # Quit with 'failed' signal
318
333
  end
319
334
  end
320
335
 
@@ -1,3 +1,3 @@
1
1
  module Parallel
2
- VERSION = Version = '0.6.5'
2
+ VERSION = Version = '0.7.0'
3
3
  end
@@ -0,0 +1,7 @@
1
+ require File.expand_path('spec/spec_helper')
2
+
3
+ Parallel.map([1,2,3], :in_processes => 2) do
4
+ puts "I finished..."
5
+ end
6
+
7
+ sleep 10
@@ -1,6 +1,12 @@
1
1
  require File.expand_path('spec/spec_helper')
2
2
 
3
- Parallel.in_processes(2) do
3
+ method = case ARGV[0]
4
+ when "PROCESS" then :in_processes
5
+ when "THREAD" then :in_threads
6
+ else raise "Learn to use this!"
7
+ end
8
+
9
+ Parallel.send(method, 2) do
4
10
  sleep 10
5
11
  puts "I should have been killed earlier..."
6
- end
12
+ end
@@ -7,6 +7,13 @@ describe Parallel do
7
7
  Time.now.to_f - t
8
8
  end
9
9
 
10
+ def kill_process_with_name(file)
11
+ running_processes = `ps -f`.split("\n").map{ |line| line.split(/\s+/) }
12
+ pid_index = running_processes.detect { |p| p.include?("UID") }.index("UID") + 1
13
+ parent_pid = running_processes.detect { |p| p.include?(file) and not p.include?("sh") }[pid_index]
14
+ `kill -2 #{parent_pid}`
15
+ end
16
+
10
17
  describe ".processor_count" do
11
18
  it "returns a number" do
12
19
  (1..999).should include(Parallel.processor_count)
@@ -58,20 +65,39 @@ describe Parallel do
58
65
 
59
66
  it "kills the processes when the main process gets killed through ctrl+c" do
60
67
  time_taken{
61
- lambda{
62
- Thread.new do
63
- `ruby spec/cases/parallel_start_and_kill.rb`
64
- end
65
- sleep 1
66
- running_processes = `ps -f`.split("\n").map{ |line| line.split(/\s+/) }
67
- pid_index = running_processes.detect{ |p| p.include?("UID") }.index("UID") + 1
68
- parent_pid = running_processes.detect{ |p| p.include?("spec/cases/parallel_start_and_kill.rb") }[pid_index]
69
- `kill -2 #{parent_pid}` #simulates Ctrl+c
70
- sleep 1
71
- }.should_not change{`ps`.split("\n").size}
68
+ lambda{
69
+ t = Thread.new { `ruby spec/cases/parallel_start_and_kill.rb PROCESS` }
70
+ sleep 1
71
+ kill_process_with_name("spec/cases/parallel_start_and_kill.rb") #simulates Ctrl+c
72
+ sleep 1
73
+ puts t.value
74
+ }.should_not change{`ps`.split("\n").size}
72
75
  }.should <= 3
73
76
  end
74
77
 
78
+ it "kills the threads when the main process gets killed through ctrl+c" do
79
+ time_taken{
80
+ lambda{
81
+ Thread.new { `ruby spec/cases/parallel_start_and_kill.rb THREAD` }
82
+ sleep 1
83
+ kill_process_with_name("spec/cases/parallel_start_and_kill.rb") #simulates Ctrl+c
84
+ sleep 1
85
+ }.should_not change{`ps`.split("\n").size}
86
+ }.should <= 3
87
+ end
88
+
89
+ it "does not kill anything on ctrl+c when everything has finished" do
90
+ time_taken do
91
+ t = Thread.new { `ruby spec/cases/parallel_fast_exit.rb 2>&1` }
92
+ sleep 2
93
+ kill_process_with_name("spec/cases/parallel_fast_exit.rb") #simulates Ctrl+c
94
+ sleep 1
95
+ result = t.value
96
+ result.scan(/I finished/).size.should == 3
97
+ result.should_not include("Parallel execution interrupted")
98
+ end.should <= 4
99
+ end
100
+
75
101
  it "saves time" do
76
102
  time_taken{
77
103
  `ruby spec/cases/parallel_sleeping_2.rb`
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -36,7 +36,7 @@ cert_chain:
36
36
  VHNmKzZNYWVud0FNa0FnSGRzd0dzSnp0T25ObkJhM0YKeTBrQ1NXbUs2RCt4
37
37
  L1NiZlM2cjdLZTA3TVJxemlKZEI5R3VFMSswY0lSdUZoOEVRK0xONkhYQ0tN
38
38
  NXBvbi9HVQp5Y3dNWGZsMAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
39
- date: 2013-05-14 00:00:00.000000000 Z
39
+ date: 2013-06-14 00:00:00.000000000 Z
40
40
  dependencies: []
41
41
  description:
42
42
  email: michael@grosser.it
@@ -69,6 +69,7 @@ files:
69
69
  - spec/cases/map_with_threads_and_break.rb
70
70
  - spec/cases/map_with_threads_and_exceptions.rb
71
71
  - spec/cases/no_dump_with_each.rb
72
+ - spec/cases/parallel_fast_exit.rb
72
73
  - spec/cases/parallel_high_fork_rate.rb
73
74
  - spec/cases/parallel_influence_outside_data.rb
74
75
  - spec/cases/parallel_map.rb
@@ -100,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
101
  version: '0'
101
102
  segments:
102
103
  - 0
103
- hash: 4198447693548042537
104
+ hash: 3171902731114170128
104
105
  required_rubygems_version: !ruby/object:Gem::Requirement
105
106
  none: false
106
107
  requirements:
@@ -109,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
110
  version: '0'
110
111
  segments:
111
112
  - 0
112
- hash: 4198447693548042537
113
+ hash: 3171902731114170128
113
114
  requirements: []
114
115
  rubyforge_project:
115
116
  rubygems_version: 1.8.25
metadata.gz.sig CHANGED
Binary file