process-group 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +12 -17
- data/.rspec +4 -2
- data/.travis.yml +12 -14
- data/Gemfile +1 -2
- data/README.md +98 -80
- data/Rakefile +2 -4
- data/lib/process/group.rb +61 -32
- data/lib/process/group/version.rb +1 -1
- data/process-group.gemspec +8 -7
- data/spec/process/group/foreground_spec.rb +34 -0
- data/spec/spec_helper.rb +34 -0
- metadata +39 -9
- data/.simplecov +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e0688415bdb9f59086dc3dbdedb5f7ad1ff15c70ef7c01c9f46c31c8a1ca4f52
|
4
|
+
data.tar.gz: 532594d9090ce8b46cb050fd68e651626f90c7370e51e848fbac53cef164aa91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1cf05b44ba660304634e6597415e3134cc108857114bdd5f46d7b4d31afcce4ebfc8a5cda70c308619ae0680f56f3bc53b93c83f8e605a64a56d866c6ac7048
|
7
|
+
data.tar.gz: 668f5a5a3fbf2e05ec1d540e841f277df3709f987ff72918137cc96066ee145bc4eee997281748b8f377d5ddce27b67b9946769bc5feaac07360d00ef082f738
|
data/.gitignore
CHANGED
@@ -1,17 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/Gemfile.lock
|
4
|
+
/_yardoc/
|
5
|
+
/coverage/
|
6
|
+
/doc/
|
7
|
+
/pkg/
|
8
|
+
/spec/reports/
|
9
|
+
/tmp/
|
10
|
+
|
11
|
+
# rspec failure tracking
|
12
|
+
.rspec_status
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
3
|
-
|
4
|
-
- 2.0.0
|
5
|
-
- 2.1.8
|
6
|
-
- 2.2.4
|
7
|
-
- 2.3.0
|
8
|
-
- ruby-head
|
9
|
-
- rbx-2
|
10
|
-
env: COVERAGE=true
|
11
|
-
matrix:
|
12
|
-
fast_finish: true
|
13
|
-
allow_failures:
|
14
|
-
- rvm: "ruby-head"
|
15
|
-
- rvm: "rbx-2"
|
2
|
+
dist: xenial
|
3
|
+
cache: bundler
|
16
4
|
|
5
|
+
matrix:
|
6
|
+
include:
|
7
|
+
- rvm: 2.3
|
8
|
+
- rvm: 2.4
|
9
|
+
- rvm: 2.5
|
10
|
+
- rvm: 2.6
|
11
|
+
- rvm: 2.6
|
12
|
+
os: osx
|
13
|
+
- rvm: 2.6
|
14
|
+
env: COVERAGE=BriefSummary,Coveralls
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,11 +2,17 @@
|
|
2
2
|
|
3
3
|
`Process::Group` allows for multiple fibers to run system processes concurrently with minimal overhead.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
```ruby
|
6
|
+
Process::Group.wait do |group|
|
7
|
+
group.run("ls", "-lah") {|status| puts status.inspect}
|
8
|
+
group.run("echo", "Hello World") {|status| puts status.inspect}
|
9
|
+
end
|
10
|
+
```
|
11
|
+
|
12
|
+
[![Build Status](https://secure.travis-ci.org/socketry/process-group.svg)](http://travis-ci.org/socketry/process-group)
|
13
|
+
[![Coverage Status](https://coveralls.io/repos/socketry/process-group/badge.svg)](https://coveralls.io/r/socketry/process-group)
|
8
14
|
[![Documentation](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/gems/process-group)
|
9
|
-
[![Code](http://img.shields.io/badge/github-code-blue.svg)](https://github.com/
|
15
|
+
[![Code](http://img.shields.io/badge/github-code-blue.svg)](https://github.com/socketry/process-group)
|
10
16
|
|
11
17
|
## Installation
|
12
18
|
|
@@ -46,17 +52,19 @@ The `group.wait` call is an explicit synchronization point, and if it completes
|
|
46
52
|
|
47
53
|
Items within a single fiber will execute sequentially. Processes (e.g. via `Group#spawn`) will run concurrently in multiple fibers.
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
```ruby
|
56
|
+
Process::Group.wait do |group|
|
57
|
+
# Explicity manage concurrency in this fiber:
|
58
|
+
Fiber.new do
|
59
|
+
# These processes will be run sequentially:
|
60
|
+
group.spawn("sleep 1")
|
61
|
+
group.spawn("sleep 1")
|
62
|
+
end.resume
|
63
|
+
|
64
|
+
# Implicitly run this task concurrently as the above fiber:
|
65
|
+
group.run("sleep 2")
|
66
|
+
end
|
67
|
+
```
|
60
68
|
|
61
69
|
`Group#spawn` is theoretically identical to `Process#spawn` except the processes are run concurrently if possible.
|
62
70
|
|
@@ -64,61 +72,69 @@ Items within a single fiber will execute sequentially. Processes (e.g. via `Grou
|
|
64
72
|
|
65
73
|
The recommended approach to use process group is to call `Process::Group.wait` with a block which invokes tasks. This block is wrapped in appropriate `rescue Interrupt` and `ensure` blocks which guarantee that the process group is cleaned up:
|
66
74
|
|
67
|
-
|
68
|
-
|
69
|
-
|
75
|
+
```ruby
|
76
|
+
Process::Group.wait do |group|
|
77
|
+
group.run("sleep 10")
|
78
|
+
end
|
79
|
+
```
|
70
80
|
|
71
81
|
It is also possible to invoke this machinery and reuse the process group simply by instantiating the group and calling wait explicitly:
|
72
82
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
83
|
+
```ruby
|
84
|
+
group = Process::Group.new
|
85
|
+
|
86
|
+
group.wait do
|
87
|
+
group.run("sleep 10")
|
88
|
+
end
|
89
|
+
```
|
78
90
|
|
79
91
|
It is also possible to queue tasks for execution outside the wait block. But by design, it's only possible to execute tasks within the wait block. Tasks added outside a wait block will be queued up for execution when `#wait` is invoked:
|
80
92
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
93
|
+
```ruby
|
94
|
+
group = Process::Group.new
|
95
|
+
|
96
|
+
group.run("sleep 10")
|
97
|
+
|
98
|
+
# Run command here:
|
99
|
+
group.wait
|
100
|
+
```
|
87
101
|
|
88
102
|
### Specify Options
|
89
103
|
|
90
104
|
You can specify options to `Group#run` and `Group#spawn` just like `Process::spawn`:
|
91
105
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
106
|
+
```ruby
|
107
|
+
Process::Group.wait do |group|
|
108
|
+
env = {'FOO' => 'BAR'}
|
109
|
+
|
110
|
+
# Arguments are essentially the same as Process::spawn.
|
111
|
+
group.run(env, "sleep 1", chdir: "/tmp")
|
112
|
+
end
|
113
|
+
```
|
98
114
|
|
99
115
|
### Process Limit
|
100
116
|
|
101
117
|
The process group can be used as a way to spawn multiple processes, but sometimes you'd like to limit the number of parallel processes to something relating to the number of processors in the system. By default, there is no limit on the number of processes running concurrently.
|
102
118
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
# 'system' gem - found very fast, less wide support (but nothing really important).
|
108
|
-
require 'system'
|
109
|
-
group = Process::Group.new(limit: System::CPU.count)
|
119
|
+
```ruby
|
120
|
+
# limit based on the number of processors:
|
121
|
+
require 'etc'
|
122
|
+
group = Process::Group.new(limit: Etc.nprocessors)
|
110
123
|
|
111
|
-
|
112
|
-
|
124
|
+
# hardcoded - set to n (8 < n < 32) and let the OS scheduler worry about it:
|
125
|
+
group = Process::Group.new(limit: 32)
|
113
126
|
|
114
|
-
|
115
|
-
|
127
|
+
# unlimited - default:
|
128
|
+
group = Process::Group.new
|
129
|
+
```
|
116
130
|
|
117
131
|
### Kill Group
|
118
132
|
|
119
133
|
It is possible to send a signal (kill) to the entire process group:
|
120
134
|
|
121
|
-
|
135
|
+
```ruby
|
136
|
+
group.kill(:TERM)
|
137
|
+
```
|
122
138
|
|
123
139
|
If there are no running processes, this is a no-op (rather than an error). [Proper handling of SIGINT/SIGQUIT](http://www.cons.org/cracauer/sigint.html) explains how to use signals correctly.
|
124
140
|
|
@@ -130,43 +146,45 @@ If there are no running processes, this is a no-op (rather than an error). [Prop
|
|
130
146
|
|
131
147
|
You can run a process group with a time limit by using a separate child process:
|
132
148
|
|
133
|
-
|
149
|
+
```ruby
|
150
|
+
group = Process::Group.new
|
151
|
+
|
152
|
+
class Timeout < StandardError
|
153
|
+
end
|
154
|
+
|
155
|
+
Fiber.new do
|
156
|
+
# Wait for 2 seconds, let other processes run:
|
157
|
+
group.fork { sleep 2 }
|
134
158
|
|
135
|
-
|
136
|
-
|
159
|
+
# If no other processes are running, we are done:
|
160
|
+
Fiber.yield unless group.running?
|
137
161
|
|
138
|
-
|
139
|
-
|
140
|
-
group.fork { sleep 2 }
|
141
|
-
|
142
|
-
# If no other processes are running, we are done:
|
143
|
-
Fiber.yield unless group.running?
|
144
|
-
|
145
|
-
# Send SIGINT to currently running processes:
|
146
|
-
group.kill(:INT)
|
147
|
-
|
148
|
-
# Wait for 2 seconds, let other processes run:
|
149
|
-
group.fork { sleep 2 }
|
150
|
-
|
151
|
-
# If no other processes are running, we are done:
|
152
|
-
Fiber.yield unless group.running?
|
153
|
-
|
154
|
-
# Send SIGTERM to currently running processes:
|
155
|
-
group.kill(:TERM)
|
156
|
-
|
157
|
-
# Raise an Timeout exception which is based back out:
|
158
|
-
raise Timeout
|
159
|
-
end.resume
|
162
|
+
# Send SIGINT to currently running processes:
|
163
|
+
group.kill(:INT)
|
160
164
|
|
161
|
-
#
|
162
|
-
group.
|
165
|
+
# Wait for 2 seconds, let other processes run:
|
166
|
+
group.fork { sleep 2 }
|
163
167
|
|
164
|
-
#
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
168
|
+
# If no other processes are running, we are done:
|
169
|
+
Fiber.yield unless group.running?
|
170
|
+
|
171
|
+
# Send SIGTERM to currently running processes:
|
172
|
+
group.kill(:TERM)
|
173
|
+
|
174
|
+
# Raise an Timeout exception which is based back out:
|
175
|
+
raise Timeout
|
176
|
+
end.resume
|
177
|
+
|
178
|
+
# Run some other long task:
|
179
|
+
group.run("sleep 10")
|
180
|
+
|
181
|
+
# Wait for fiber to complete:
|
182
|
+
begin
|
183
|
+
group.wait
|
184
|
+
rescue Timeout
|
185
|
+
puts "Process group was terminated forcefully."
|
186
|
+
end
|
187
|
+
```
|
170
188
|
|
171
189
|
## Contributing
|
172
190
|
|
data/Rakefile
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
|
4
|
-
RSpec::Core::RakeTask.new(:
|
5
|
-
task.rspec_opts = ["--require", "simplecov"] if ENV['COVERAGE']
|
6
|
-
end
|
4
|
+
RSpec::Core::RakeTask.new(:test)
|
7
5
|
|
8
|
-
task :default => :
|
6
|
+
task :default => :test
|
data/lib/process/group.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'fiber'
|
22
|
+
require 'process/terminal'
|
22
23
|
|
23
24
|
module Process
|
24
25
|
# A group of tasks which can be run asynchrnously using fibers. Someone must call Group#wait to ensure that all fibers eventually resume.
|
@@ -29,70 +30,88 @@ module Process
|
|
29
30
|
group.wait(&block)
|
30
31
|
end
|
31
32
|
|
32
|
-
# Executes a command using Process.spawn with the given arguments and options.
|
33
33
|
class Command
|
34
|
-
def initialize(
|
35
|
-
@arguments = arguments
|
34
|
+
def initialize(foreground: false, **options)
|
36
35
|
@options = options
|
37
|
-
|
38
|
-
|
36
|
+
@foreground = foreground
|
37
|
+
|
38
|
+
@fiber = Fiber.current
|
39
|
+
@pid = nil
|
39
40
|
end
|
40
|
-
|
41
|
-
attr :arguments
|
41
|
+
|
42
42
|
attr :options
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
|
44
|
+
attr :pid
|
45
|
+
|
46
|
+
def foreground?
|
47
|
+
@foreground
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def resume(*arguments)
|
51
51
|
@fiber.resume(*arguments)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
#
|
56
|
-
class
|
57
|
-
def initialize(
|
58
|
-
@
|
55
|
+
# Executes a command using Process.spawn with the given arguments and options.
|
56
|
+
class Spawn < Command
|
57
|
+
def initialize(arguments, **options)
|
58
|
+
@arguments = arguments
|
59
|
+
|
60
|
+
super(**options)
|
61
|
+
end
|
62
|
+
|
63
|
+
attr :arguments
|
64
|
+
|
65
|
+
def call(**options)
|
66
|
+
options = @options.merge(options)
|
59
67
|
|
60
|
-
|
68
|
+
@pid = Process.spawn(*@arguments, **options)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Runs a given block using a forked process.
|
73
|
+
class Fork < Command
|
74
|
+
def initialize(block, **options)
|
75
|
+
@block = block
|
61
76
|
|
62
|
-
|
77
|
+
super(**options)
|
63
78
|
end
|
64
79
|
|
65
|
-
def
|
80
|
+
def call(**options)
|
81
|
+
options = @options.merge(options)
|
82
|
+
|
66
83
|
@pid = Process.fork(&@block)
|
67
84
|
|
68
85
|
if options[:pgroup] == true
|
69
86
|
# Establishes the child process as a process group leader:
|
70
87
|
Process.setpgid(@pid, 0)
|
71
|
-
|
88
|
+
elsif pgroup = options[:pgroup]
|
72
89
|
# Set this process as part of the existing process group:
|
73
|
-
Process.setpgid(@pid,
|
90
|
+
Process.setpgid(@pid, pgroup)
|
74
91
|
end
|
75
92
|
|
76
93
|
return @pid
|
77
94
|
end
|
78
|
-
|
95
|
+
|
79
96
|
def resume(*arguments)
|
80
97
|
@fiber.resume(*arguments)
|
81
98
|
end
|
82
99
|
end
|
83
100
|
|
84
101
|
# Create a new process group. Can specify `limit:` which limits the maximum number of concurrent processes.
|
85
|
-
def initialize(limit: nil)
|
102
|
+
def initialize(limit: nil, terminal: Terminal::Device.open)
|
86
103
|
raise ArgumentError.new("Limit must be nil (unlimited) or > 0") unless limit == nil or limit > 0
|
87
104
|
|
88
105
|
@pid = Process.pid
|
89
106
|
|
107
|
+
@terminal = terminal
|
108
|
+
|
90
109
|
@queue = []
|
91
110
|
@limit = limit
|
92
|
-
|
111
|
+
|
93
112
|
@running = {}
|
94
113
|
@fiber = nil
|
95
|
-
|
114
|
+
|
96
115
|
@pgid = nil
|
97
116
|
|
98
117
|
# Whether we can actively schedule tasks or not:
|
@@ -130,14 +149,20 @@ module Process
|
|
130
149
|
end.resume
|
131
150
|
end
|
132
151
|
|
152
|
+
def async
|
153
|
+
Fiber.new do
|
154
|
+
yield self
|
155
|
+
end.resume
|
156
|
+
end
|
157
|
+
|
133
158
|
# Run a specific command as a child process.
|
134
159
|
def spawn(*arguments, **options)
|
135
|
-
append!
|
160
|
+
append! Spawn.new(arguments, **options)
|
136
161
|
end
|
137
162
|
|
138
163
|
# Fork a block as a child process.
|
139
164
|
def fork(**options, &block)
|
140
|
-
append! Fork.new(block, options)
|
165
|
+
append! Fork.new(block, **options)
|
141
166
|
end
|
142
167
|
|
143
168
|
# Whether or not #spawn, #fork or #run can be scheduled immediately.
|
@@ -202,7 +227,7 @@ module Process
|
|
202
227
|
end
|
203
228
|
|
204
229
|
def to_s
|
205
|
-
"#<#{self.class} running=#{@running.size} queued=#{@queue.
|
230
|
+
"#<#{self.class} running=#{@running.size} queued=#{@queue.size} limit=#{@limit} pgid=#{@pgid}>"
|
206
231
|
end
|
207
232
|
|
208
233
|
private
|
@@ -236,14 +261,18 @@ module Process
|
|
236
261
|
def schedule!
|
237
262
|
while available? and @queue.size > 0
|
238
263
|
process = @queue.shift
|
239
|
-
|
264
|
+
|
240
265
|
if @running.size == 0
|
241
|
-
pid = process.
|
266
|
+
pid = process.call(:pgroup => true)
|
242
267
|
|
243
268
|
# The process group id is the pid of the first process:
|
244
269
|
@pgid = pid
|
245
270
|
else
|
246
|
-
pid = process.
|
271
|
+
pid = process.call(:pgroup => @pgid)
|
272
|
+
end
|
273
|
+
|
274
|
+
if @terminal and process.foreground?
|
275
|
+
@terminal.foreground = pid
|
247
276
|
end
|
248
277
|
|
249
278
|
@running[pid] = process
|
data/process-group.gemspec
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'process/group/version'
|
1
|
+
|
2
|
+
require_relative 'lib/process/group/version'
|
5
3
|
|
6
4
|
Gem::Specification.new do |spec|
|
7
5
|
spec.name = "process-group"
|
@@ -19,10 +17,13 @@ Gem::Specification.new do |spec|
|
|
19
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
19
|
spec.require_paths = ["lib"]
|
22
|
-
|
20
|
+
|
23
21
|
spec.required_ruby_version = '>= 2.0'
|
24
|
-
|
25
|
-
spec.
|
22
|
+
|
23
|
+
spec.add_dependency "process-terminal"
|
24
|
+
|
25
|
+
spec.add_development_dependency "covered"
|
26
|
+
spec.add_development_dependency "bundler"
|
26
27
|
spec.add_development_dependency "rspec", "~> 3.4.0"
|
27
28
|
spec.add_development_dependency "rake"
|
28
29
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright, 2015, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'process/group'
|
22
|
+
|
23
|
+
RSpec.describe Process::Group do
|
24
|
+
it "can run a process in the foreground" do
|
25
|
+
output, input = IO.pipe
|
26
|
+
|
27
|
+
subject.wait do
|
28
|
+
subject.run("irb", foreground: true, in: output)
|
29
|
+
|
30
|
+
input.puts("exit")
|
31
|
+
input.close
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require "bundler/setup"
|
22
|
+
require 'covered/rspec'
|
23
|
+
|
24
|
+
RSpec.configure do |config|
|
25
|
+
# Enable flags like --only-failures and --next-failure
|
26
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
27
|
+
|
28
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
29
|
+
config.disable_monkey_patching!
|
30
|
+
|
31
|
+
config.expect_with :rspec do |c|
|
32
|
+
c.syntax = :expect
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: process-group
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: process-terminal
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: covered
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
16
44
|
requirements:
|
17
|
-
- - "
|
45
|
+
- - ">="
|
18
46
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
47
|
+
version: '0'
|
20
48
|
type: :development
|
21
49
|
prerelease: false
|
22
50
|
version_requirements: !ruby/object:Gem::Requirement
|
23
51
|
requirements:
|
24
|
-
- - "
|
52
|
+
- - ">="
|
25
53
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rspec
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -63,7 +91,6 @@ extra_rdoc_files: []
|
|
63
91
|
files:
|
64
92
|
- ".gitignore"
|
65
93
|
- ".rspec"
|
66
|
-
- ".simplecov"
|
67
94
|
- ".travis.yml"
|
68
95
|
- Gemfile
|
69
96
|
- README.md
|
@@ -72,6 +99,7 @@ files:
|
|
72
99
|
- lib/process/group.rb
|
73
100
|
- lib/process/group/version.rb
|
74
101
|
- process-group.gemspec
|
102
|
+
- spec/process/group/foreground_spec.rb
|
75
103
|
- spec/process/group/fork_spec.rb
|
76
104
|
- spec/process/group/interrupt_spec.rb
|
77
105
|
- spec/process/group/io_spec.rb
|
@@ -79,6 +107,7 @@ files:
|
|
79
107
|
- spec/process/group/process_spec.rb
|
80
108
|
- spec/process/group/spawn_spec.rb
|
81
109
|
- spec/process/group/wait_spec.rb
|
110
|
+
- spec/spec_helper.rb
|
82
111
|
homepage: https://github.com/ioquatix/process-group
|
83
112
|
licenses:
|
84
113
|
- MIT
|
@@ -98,12 +127,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
127
|
- !ruby/object:Gem::Version
|
99
128
|
version: '0'
|
100
129
|
requirements: []
|
101
|
-
|
102
|
-
rubygems_version: 2.5.1
|
130
|
+
rubygems_version: 3.0.6
|
103
131
|
signing_key:
|
104
132
|
specification_version: 4
|
105
133
|
summary: Run processes concurrently in separate fibers with predictable behaviour.
|
106
134
|
test_files:
|
135
|
+
- spec/process/group/foreground_spec.rb
|
107
136
|
- spec/process/group/fork_spec.rb
|
108
137
|
- spec/process/group/interrupt_spec.rb
|
109
138
|
- spec/process/group/io_spec.rb
|
@@ -111,3 +140,4 @@ test_files:
|
|
111
140
|
- spec/process/group/process_spec.rb
|
112
141
|
- spec/process/group/spawn_spec.rb
|
113
142
|
- spec/process/group/wait_spec.rb
|
143
|
+
- spec/spec_helper.rb
|