parallel 0.6.5 → 0.7.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.
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