team_effort 0.0.9 → 1.0.1

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
  SHA256:
3
- metadata.gz: 267e445b9850df939f36b9458ed000f4889867bc3c686fb4410b5e6acf2d6f31
4
- data.tar.gz: 0a6673448d5e06aa98d7e760c6df4e773008747241e7012a7217c37357e9fcee
3
+ metadata.gz: 2d7779d24f1c2aa78460778a38d505c106677eab6afe2c829ebd551b169ce551
4
+ data.tar.gz: 2f96281c9c5558d23d4bb49153d450bd8a4617b0ec551d93fcb6ebab5de13246
5
5
  SHA512:
6
- metadata.gz: d60080c326dd3acbe4e2886d858919e92e01c94e9aa6fa629ffca35829d27868eb674d49bf572fae5bcf9c26939a1ed40047333eb5d122b01b51e864bcfd0b8c
7
- data.tar.gz: d1c1a4f3f6ff5fd9b0539df97487d02d5576278c770cab598d26799d81185c61b852f013ada2963167953bf3391f1c675954fc6896d191d923cd73fd24a16b54
6
+ metadata.gz: 7090174299461bd8e9d50190c3b7d10cede4fcb918985d741c72e629860ee2b98f866daf0c512f3b5fe5c452ca07972c70e09bd39d8f858d671e74ffa9bd5e66
7
+ data.tar.gz: 24a64b1dbaf6b2b6f4d6718bd49cf208e9cb92f6c3d86ef0b5d3c28afc71eba4a65b0e72eb5707eecf09bfda6318de90be6dee044df69fc86e936444ddc7f629
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## 1.0.0 (2019-01-07)
2
+
3
+ - Potential breaking change: In previous versions, a child process returning a non 0 exit status had no effect. With
4
+ this version, non 0 exit statuses raise an exception in the main process.
5
+
@@ -1,3 +1,3 @@
1
1
  module TeamEffort
2
- VERSION = "0.0.9"
2
+ VERSION = "1.0.1"
3
3
  end
data/lib/team_effort.rb CHANGED
@@ -3,25 +3,44 @@ require_relative "team_effort/version"
3
3
  module TeamEffort
4
4
  def self.work(enumerable, max_process_count = 4, progress_proc: nil)
5
5
  pids = []
6
+ arg_sets = []
7
+
6
8
  max_count = enumerable.count
7
9
  completed_count = 0
8
10
 
9
- enumerable.each do |args|
11
+ enumerable.each do |arg_set|
10
12
  while pids.size == max_process_count
11
- finished_pid = Process.wait
12
- pids.delete finished_pid
13
- progress_proc.call(completed_count += 1, max_count) if progress_proc
13
+ pids, arg_sets, completed_count = wait_for_completion(pids, arg_sets, completed_count, max_count, progress_proc)
14
14
  end
15
15
 
16
16
  pids << fork do
17
- yield args
17
+ begin
18
+ yield arg_set
19
+ exit! 0
20
+ rescue => e
21
+ $stderr.puts "TeamEffort child process error"
22
+ $stderr.puts e
23
+ $stderr.puts caller
24
+ exit! 1
25
+ end
18
26
  end
27
+ arg_sets << arg_set
19
28
  end
20
29
 
21
30
  while !pids.empty?
22
- finished_pid = Process.wait
23
- pids.delete finished_pid
24
- progress_proc.call(completed_count += 1, max_count) if progress_proc
31
+ pids, arg_sets, completed_count = wait_for_completion(pids, arg_sets, completed_count, max_count, progress_proc)
32
+ end
33
+ end
34
+
35
+ def self.wait_for_completion(pids, arg_sets, completed_count, max_count, progress_proc)
36
+ pid, status = Process.wait2
37
+ pids_index = pids.index(pid)
38
+ if pids_index
39
+ pids.delete_at pids_index
40
+ arg_set = arg_sets.delete_at pids_index
41
+ raise "TeamEffort child process failed when processing > #{arg_set} <" if !status.success?
25
42
  end
43
+ progress_proc.call(completed_count += 1, max_count) if progress_proc
44
+ [pids, arg_sets, completed_count]
26
45
  end
27
46
  end
@@ -26,16 +26,32 @@ describe TeamEffort do
26
26
  lines = output.split(/\n/)
27
27
  lines.size.must_equal 3
28
28
  lines.each do |line|
29
- line.must_match /^\d+$/
29
+ line.must_match(/^\d+$/)
30
30
  end
31
31
  end
32
32
 
33
+ it 'exits when a child process fails' do
34
+ data = [8, 4, 2, 0, 4, 8]
35
+
36
+ err = -> {
37
+ $stderr = File.open('/dev/null', 'w')
38
+ begin
39
+ TeamEffort.work(data, 1) do |item|
40
+ 16 / item
41
+ end
42
+ ensure
43
+ $stderr.close
44
+ $stderr = STDERR
45
+ end
46
+ }.must_raise RuntimeError
47
+ err.message.must_match /TeamEffort child process failed when processing > 0 </
48
+ end
49
+
33
50
  it 'invokes an optional proc when it completes an item' do
34
51
  data = %w|one two three|
35
52
  proc_data = []
36
- # proc = ->(item_index, max_items) {proc_data << [item_index, max_items]}
37
- progress_proc = ->(index, max_index) { puts "#{ sprintf("%3i%", index.to_f / max_index * 100) }" }
38
- TeamEffort.work(data, 1, progress_proc: progress_proc) {}
53
+ proc = ->(item_index, max_items) { proc_data << [item_index, max_items] }
54
+ TeamEffort.work(data, 1, progress_proc: proc) {}
39
55
 
40
56
  proc_data.must_equal [
41
57
  [1, 3],
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: team_effort
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelly Felkins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-14 00:00:00.000000000 Z
11
+ date: 2019-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -49,13 +49,14 @@ files:
49
49
  - ".gitignore"
50
50
  - ".ruby-gemset"
51
51
  - ".ruby-version"
52
+ - CHANGELOG.md
52
53
  - LICENSE
53
54
  - README.md
54
55
  - Rakefile
55
56
  - lib/team_effort.rb
56
57
  - lib/team_effort/version.rb
57
58
  - team_effort.gemspec
58
- - test/test_team_effort.rb
59
+ - test/team_effort_test.rb
59
60
  homepage: https://github.com/kellyfelkins/team_effort
60
61
  licenses:
61
62
  - MIT
@@ -81,4 +82,4 @@ signing_key:
81
82
  specification_version: 4
82
83
  summary: Use child processes to process a collection in parallel
83
84
  test_files:
84
- - test/test_team_effort.rb
85
+ - test/team_effort_test.rb