in-parallel 0.1.15 → 0.1.16
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 +13 -5
- data/HISTORY.md +57 -2
- data/lib/in-parallel/version.rb +1 -1
- data/lib/in_parallel.rb +31 -27
- data/spec/in-paralell_spec.rb +13 -0
- metadata +5 -7
- data/Gemfile.lock +0 -68
checksums.yaml
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
NGJlY2ZkMDkyMjM3MGE4NGIxNjljNDU1YTE1NGRkYWY2OWE2NjZkZA==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
ZmQ4NmExZGJmYmZiNDM5NjM1MWQ1OGM5MTMwMGMwMjYzMDdjY2ViOQ==
|
|
5
7
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
MGFjZTBkNGUzYTEwYWFkMDY0YWVhNGIxNjc2MzhkOWUwNTg5Y2NjNmQxOTAy
|
|
10
|
+
ZjAwNTliZWJmZTU4NjU1ODg0OGExNmRkZTljMzk0OWQyZGU2ODFhOWQ3ZTUw
|
|
11
|
+
ZWQzNTRkMjY5YzM5MGYyZGViNGY4MjVhMjQwMDExYjE5MTQ3ZWY=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
OWEyOGQ2MWJiY2RiZTVhNTMxM2VhNDllM2MwNmM2ZTVjNWVhNjljMjcxZDU4
|
|
14
|
+
NWIxNTAxNzMyZDM1YWZlYjhhOWQ2Y2I0NzRmNGZmOWJlN2EzOTlhYTA5ZTk2
|
|
15
|
+
NDZlZGVhYmYyYzFkOTcwN2E0MWY4NjQ1NTEzOGZmMGE0OGE0MWM=
|
data/HISTORY.md
CHANGED
|
@@ -1,10 +1,65 @@
|
|
|
1
1
|
# experimental_in-parallel_bump_and_tag_master - History
|
|
2
2
|
## Tags
|
|
3
|
-
* [LATEST -
|
|
3
|
+
* [LATEST - 6 Feb, 2017 (27b497ea)](#LATEST)
|
|
4
|
+
* [0.1.15 - 3 Feb, 2017 (ff16929c)](#0.1.15)
|
|
5
|
+
* [0.1.14 - 8 Aug, 2016 (ce331dbd)](#0.1.14)
|
|
4
6
|
* [0.1.13 - 8 Aug, 2016 (26d19934)](#0.1.13)
|
|
5
7
|
|
|
6
8
|
## Details
|
|
7
|
-
### <a name = "LATEST">LATEST -
|
|
9
|
+
### <a name = "LATEST">LATEST - 6 Feb, 2017 (27b497ea)
|
|
10
|
+
|
|
11
|
+
* (GEM) update in-parallel version to 0.1.16 (27b497ea)
|
|
12
|
+
|
|
13
|
+
### <a name = "0.1.15">0.1.15 - 3 Feb, 2017 (ff16929c)
|
|
14
|
+
|
|
15
|
+
* (HISTORY) update in-parallel history for gem release 0.1.15 (ff16929c)
|
|
16
|
+
|
|
17
|
+
* (GEM) update in-parallel version to 0.1.15 (206a62fe)
|
|
18
|
+
|
|
19
|
+
* Merge pull request #16 from nicklewis/support-large-results (4d644d88)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Merge pull request #16 from nicklewis/support-large-results
|
|
24
|
+
|
|
25
|
+
(maint) Avoid deadlock with large results
|
|
26
|
+
```
|
|
27
|
+
* (maint) Avoid deadlock with large results (a5a9c174)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
(maint) Avoid deadlock with large results
|
|
32
|
+
|
|
33
|
+
Previously, if the result of a process was larger than the IO buffer
|
|
34
|
+
size (commonly 64k), execution would deadlock until the timeout.
|
|
35
|
+
|
|
36
|
+
In this scenario, the writer would fill the buffer and block until the
|
|
37
|
+
reader had cleared the buffer by reading. However, the reader will only
|
|
38
|
+
try to read once (to get the whole result) and will only attempt to read
|
|
39
|
+
after the child process has exited. This causes a deadlock, as the child
|
|
40
|
+
can't exit because it can't finish writing, but the the reader won't
|
|
41
|
+
read because the child hasn't exited.
|
|
42
|
+
|
|
43
|
+
This commit fixes the watcher loop to instead IO.select() from the
|
|
44
|
+
available result readers and read a partial result into a buffer whenever it's
|
|
45
|
+
available. This ensures that the writer will never remain blocked by a
|
|
46
|
+
full buffer. The reader now uses IO#eof? to determine whether the child
|
|
47
|
+
process has exited, at which point it will process the whole result as
|
|
48
|
+
before.
|
|
49
|
+
```
|
|
50
|
+
* Merge pull request #15 from samwoods1/add_jjb_pipelines (72d32635)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Merge pull request #15 from samwoods1/add_jjb_pipelines
|
|
55
|
+
|
|
56
|
+
(maint) Revert name change of in_parallel.rb
|
|
57
|
+
```
|
|
58
|
+
* (maint) Revert name change of in_parallel.rb (327c8fd5)
|
|
59
|
+
|
|
60
|
+
### <a name = "0.1.14">0.1.14 - 8 Aug, 2016 (ce331dbd)
|
|
61
|
+
|
|
62
|
+
* (HISTORY) update in-parallel history for gem release 0.1.14 (ce331dbd)
|
|
8
63
|
|
|
9
64
|
* (GEM) update in-parallel version to 0.1.14 (d026c624)
|
|
10
65
|
|
data/lib/in-parallel/version.rb
CHANGED
data/lib/in_parallel.rb
CHANGED
|
@@ -126,34 +126,37 @@ module InParallel
|
|
|
126
126
|
kill_child_processes
|
|
127
127
|
raise_error = ::RuntimeError.new("Child process ran longer than timeout of #{timeout}")
|
|
128
128
|
end
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
129
|
+
|
|
130
|
+
if result = IO.select(@@process_infos.map {|p| p[:result]}, nil, nil, 0.5)
|
|
131
|
+
read_ios = result.first
|
|
132
|
+
read_ios.each do |reader|
|
|
133
|
+
process_info = @@process_infos.find {|p| p[:result] == reader}
|
|
134
|
+
process_info[:result_buffer] << reader.read
|
|
135
|
+
if reader.eof?
|
|
136
|
+
result = process_info[:result_buffer].string
|
|
137
|
+
# the process completed, get the result and rethrow on error.
|
|
138
|
+
begin
|
|
139
|
+
# Print the STDOUT and STDERR for each process with signals for start and end
|
|
140
|
+
@@logger.info "------ Begin output for #{process_info[:method_sym]} - #{process_info[:pid]}"
|
|
141
|
+
# Content from the other thread will already be pre-pended with log stuff (info, warn, date/time, etc)
|
|
142
|
+
# So don't use logger, just use puts.
|
|
143
|
+
puts " " + File.new(process_info[:std_out], 'r').readlines.join(" ")
|
|
144
|
+
@@logger.info "------ Completed output for #{process_info[:method_sym]} - #{process_info[:pid]}"
|
|
145
|
+
marshalled_result = (result.nil? || result.empty?) ? result : Marshal.load(result)
|
|
146
|
+
# Kill all other processes and let them log their stdout before re-raising
|
|
147
|
+
# if a child process raised an error.
|
|
148
|
+
if marshalled_result.is_a?(Exception)
|
|
149
|
+
raise_error = marshalled_result.dup
|
|
150
|
+
kill_child_processes if kill_all_on_error
|
|
151
|
+
marshalled_result = nil
|
|
152
|
+
end
|
|
153
|
+
results_map[process_info[:index]] = { process_info[:tmp_result] => marshalled_result }
|
|
154
|
+
ensure
|
|
155
|
+
File.delete(process_info[:std_out]) if File.exists?(process_info[:std_out])
|
|
156
|
+
# close the read end pipe
|
|
157
|
+
process_info[:result].close unless process_info[:result].closed?
|
|
158
|
+
@@process_infos.delete(process_info)
|
|
150
159
|
end
|
|
151
|
-
results_map[process_info[:index]] = { process_info[:tmp_result] => marshalled_result }
|
|
152
|
-
ensure
|
|
153
|
-
File.delete(process_info[:std_out]) if File.exists?(process_info[:std_out])
|
|
154
|
-
# close the read end pipe
|
|
155
|
-
process_info[:result].close unless process_info[:result].closed?
|
|
156
|
-
@@process_infos.delete(process_info)
|
|
157
160
|
end
|
|
158
161
|
end
|
|
159
162
|
end
|
|
@@ -235,6 +238,7 @@ module InParallel
|
|
|
235
238
|
:std_out => "tmp/pp_#{pid}",
|
|
236
239
|
:result => read_result,
|
|
237
240
|
:tmp_result => "unresolved_parallel_result_#{@@result_id}",
|
|
241
|
+
:result_buffer => StringIO.new,
|
|
238
242
|
:index => @@process_infos.count }
|
|
239
243
|
@@process_infos.push(process_info)
|
|
240
244
|
@@result_id += 1
|
data/spec/in-paralell_spec.rb
CHANGED
|
@@ -101,6 +101,19 @@ describe '.run_in_parallel' do
|
|
|
101
101
|
expect(@result_2).to eq({ :foo => "bar" })
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
+
it "should return large results" do
|
|
105
|
+
# 2**16 = 64k is typical buffer size
|
|
106
|
+
long_string = 'a' * (2**16+1)
|
|
107
|
+
|
|
108
|
+
expect do
|
|
109
|
+
run_in_parallel(timeout=1) do
|
|
110
|
+
@result = method_with_param(long_string)
|
|
111
|
+
end
|
|
112
|
+
end.not_to raise_error
|
|
113
|
+
|
|
114
|
+
expect(@result).to eq "bar + #{long_string}"
|
|
115
|
+
end
|
|
116
|
+
|
|
104
117
|
it "should return a singleton class value" do
|
|
105
118
|
|
|
106
119
|
run_in_parallel { @result = get_singleton_class }
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: in-parallel
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- samwoods1
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-02-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Many other Ruby libraries that simplify parallel execution support one
|
|
14
14
|
primary use case - crunching through a large queue of small, similar tasks as quickly
|
|
@@ -26,7 +26,6 @@ extra_rdoc_files: []
|
|
|
26
26
|
files:
|
|
27
27
|
- CONTRIBUTING.md
|
|
28
28
|
- Gemfile
|
|
29
|
-
- Gemfile.lock
|
|
30
29
|
- HISTORY.md
|
|
31
30
|
- LICENSE
|
|
32
31
|
- MAINTAINERS.md
|
|
@@ -47,20 +46,19 @@ require_paths:
|
|
|
47
46
|
- lib
|
|
48
47
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
48
|
requirements:
|
|
50
|
-
- -
|
|
49
|
+
- - ! '>='
|
|
51
50
|
- !ruby/object:Gem::Version
|
|
52
51
|
version: '0'
|
|
53
52
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
53
|
requirements:
|
|
55
|
-
- -
|
|
54
|
+
- - ! '>='
|
|
56
55
|
- !ruby/object:Gem::Version
|
|
57
56
|
version: '0'
|
|
58
57
|
requirements: []
|
|
59
58
|
rubyforge_project:
|
|
60
|
-
rubygems_version: 2.
|
|
59
|
+
rubygems_version: 2.4.6
|
|
61
60
|
signing_key:
|
|
62
61
|
specification_version: 4
|
|
63
62
|
summary: A lightweight library to execute a handful of tasks in parallel with simple
|
|
64
63
|
syntax
|
|
65
64
|
test_files: []
|
|
66
|
-
has_rdoc:
|
data/Gemfile.lock
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
in-parallel (0.1.12)
|
|
5
|
-
|
|
6
|
-
GEM
|
|
7
|
-
remote: https://rubygems.org/
|
|
8
|
-
specs:
|
|
9
|
-
activesupport (4.2.6)
|
|
10
|
-
i18n (~> 0.7)
|
|
11
|
-
json (~> 1.7, >= 1.7.7)
|
|
12
|
-
minitest (~> 5.1)
|
|
13
|
-
thread_safe (~> 0.3, >= 0.3.4)
|
|
14
|
-
tzinfo (~> 1.1)
|
|
15
|
-
diff-lcs (1.2.5)
|
|
16
|
-
docile (1.1.5)
|
|
17
|
-
i18n (0.7.0)
|
|
18
|
-
json (1.8.3)
|
|
19
|
-
kramdown (1.11.1)
|
|
20
|
-
logutils (0.6.1)
|
|
21
|
-
markdown (0.4.0)
|
|
22
|
-
kramdown (>= 0.13.7)
|
|
23
|
-
props (>= 0.2.0)
|
|
24
|
-
textutils (>= 0.2.0)
|
|
25
|
-
minitest (5.9.0)
|
|
26
|
-
props (1.1.2)
|
|
27
|
-
rake (10.5.0)
|
|
28
|
-
rspec (3.1.0)
|
|
29
|
-
rspec-core (~> 3.1.0)
|
|
30
|
-
rspec-expectations (~> 3.1.0)
|
|
31
|
-
rspec-mocks (~> 3.1.0)
|
|
32
|
-
rspec-core (3.1.7)
|
|
33
|
-
rspec-support (~> 3.1.0)
|
|
34
|
-
rspec-expectations (3.1.2)
|
|
35
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
36
|
-
rspec-support (~> 3.1.0)
|
|
37
|
-
rspec-mocks (3.1.3)
|
|
38
|
-
rspec-support (~> 3.1.0)
|
|
39
|
-
rspec-support (3.1.2)
|
|
40
|
-
rubyzip (1.2.0)
|
|
41
|
-
simplecov (0.11.2)
|
|
42
|
-
docile (~> 1.1.0)
|
|
43
|
-
json (~> 1.8)
|
|
44
|
-
simplecov-html (~> 0.10.0)
|
|
45
|
-
simplecov-html (0.10.0)
|
|
46
|
-
textutils (1.4.0)
|
|
47
|
-
activesupport
|
|
48
|
-
logutils (>= 0.6.1)
|
|
49
|
-
props (>= 1.1.2)
|
|
50
|
-
rubyzip (>= 1.0.0)
|
|
51
|
-
thread_safe (0.3.5)
|
|
52
|
-
tzinfo (1.2.2)
|
|
53
|
-
thread_safe (~> 0.1)
|
|
54
|
-
yard (0.9.0)
|
|
55
|
-
|
|
56
|
-
PLATFORMS
|
|
57
|
-
ruby
|
|
58
|
-
|
|
59
|
-
DEPENDENCIES
|
|
60
|
-
in-parallel!
|
|
61
|
-
markdown (~> 0)
|
|
62
|
-
rake (>= 0.9.0)
|
|
63
|
-
rspec (~> 3.1.0)
|
|
64
|
-
simplecov
|
|
65
|
-
yard (~> 0)
|
|
66
|
-
|
|
67
|
-
BUNDLED WITH
|
|
68
|
-
1.12.3
|