restartable 0.2.0 → 0.2.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 +8 -8
- data/.travis.yml +0 -2
- data/LICENSE.txt +1 -1
- data/README.markdown +1 -1
- data/features/restarting.feature +11 -9
- data/features/step_definitions/restartable_steps.rb +20 -9
- data/lib/restartable.rb +15 -7
- data/restartable.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
N2YwNjQxOGVjNzBlNjE1NjM0NjcxMDkyMWJhMDEwMGQ2MDRhOWU1MQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YmI0NmU2ZWQ3YTU4NzFlYzM0M2IzYmJiYjBlNGYxYjI0ZTNmZDI2Mg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZTA3MmE2NzczZTY3NjkxMWVlOGYzOWU4Njc2OTFkNTcxYmExYzBjMTMwOTFm
|
10
|
+
YTQyOTkyN2NlZjJkMjk5Y2ZmYzJkYWUzOGUwYzc1NTU3YjQwMmRkZGFlN2Ew
|
11
|
+
Y2RhYTM2NWNmZmQ2YzUzYjJkZjU4OGJhODY3NmY3YmMwNGZjNzk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTZmMWY2ZTM4MmViZTc1MGE5YTE4Yjg5ZDk3NmE3ZGY1YWMyNTdhNzYzMDA0
|
14
|
+
ODVhMjdjZmViNWQ0YmJlN2M5ZjFmMmU2Yjg0MTJhMmQxZmFlMmI1Zjk3YmIw
|
15
|
+
ZmM2YmZmODM0ZTVmNTBiYjAyYjg4YzgwYzMzMTJlZTQ0NDhmYTQ=
|
data/.travis.yml
CHANGED
data/LICENSE.txt
CHANGED
data/README.markdown
CHANGED
data/features/restarting.feature
CHANGED
@@ -14,17 +14,19 @@ Feature: Restarting
|
|
14
14
|
When I have waited for 1 second
|
15
15
|
Then I should see "^C to restart, double ^C to stop" in stderr
|
16
16
|
And I should see "Hello world!" in stdout
|
17
|
-
And there should be inner process
|
17
|
+
And there should be an inner process
|
18
18
|
When I interrupt restartable twice
|
19
|
-
Then I should see "Killing children…" and "Don't restart!" in
|
19
|
+
Then I should see "Killing children…" and "Don't restart!" in stderr
|
20
20
|
And inner process should terminate
|
21
21
|
And restartable should finish
|
22
22
|
|
23
23
|
Examples:
|
24
|
-
| code
|
25
|
-
| $stdout.puts "Hello world!"
|
26
|
-
| $stdout.puts "Hello world!"; sleep
|
27
|
-
| exec 'echo "Hello world!"; sleep
|
28
|
-
| system 'echo "Hello world!"; sleep
|
29
|
-
| fork{ $stdout.puts "Hello world!"; sleep
|
30
|
-
| fork{ fork{ fork{ $stdout.puts "Hello world!"; sleep
|
24
|
+
| code |
|
25
|
+
| $stdout.puts "Hello world!" |
|
26
|
+
| $stdout.puts "Hello world!"; 100.times{ sleep 1 } |
|
27
|
+
| exec 'echo "Hello world!"; sleep 100' |
|
28
|
+
| system 'echo "Hello world!"; sleep 100' |
|
29
|
+
| fork{ $stdout.puts "Hello world!"; 100.times{ sleep 1 } } |
|
30
|
+
| fork{ fork{ fork{ $stdout.puts "Hello world!"; 100.times{ sleep 1 } } } } |
|
31
|
+
| Signal.trap("INT"){}; $stdout.puts "Hello world!"; 100.times{ sleep 1 } |
|
32
|
+
| Signal.trap("INT"){}; Signal.trap("TERM"){}; $stdout.puts "Hello world!"; 100.times{ sleep 1 } |
|
@@ -33,13 +33,14 @@ Then(/^I should see "(.*?)" in stdout$/) do |string|
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
Then(/^I should see "(.*?)" in
|
37
|
-
Timeout::timeout(
|
36
|
+
Then(/^I should see "(.*?)" in stderr$/) do |arg|
|
37
|
+
Timeout::timeout(60) do
|
38
38
|
strings = arg.split(/".*?"/)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
until strings.empty?
|
40
|
+
line = @stderr[0].gets
|
41
|
+
strings.reject! do |string|
|
42
|
+
line.include?(string)
|
43
|
+
end
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -55,13 +56,23 @@ When(/^I interrupt restartable twice$/) do
|
|
55
56
|
end
|
56
57
|
|
57
58
|
Then(/^there should be an inner process$/) do
|
58
|
-
|
59
|
+
Timeout::timeout(5) do
|
60
|
+
until Sys::ProcTable.ps.any?{ |pe| pe.ppid == @pid }
|
61
|
+
sleep 1
|
62
|
+
end
|
63
|
+
end
|
59
64
|
end
|
60
65
|
|
61
66
|
Then(/^inner process should terminate$/) do
|
62
|
-
|
67
|
+
Timeout::timeout(100) do
|
68
|
+
until Sys::ProcTable.ps.none?{ |pe| pe.ppid == @pid }
|
69
|
+
sleep 1
|
70
|
+
end
|
71
|
+
end
|
63
72
|
end
|
64
73
|
|
65
74
|
Then(/^restartable should finish$/) do
|
66
|
-
|
75
|
+
Timeout::timeout(5) do
|
76
|
+
Process.wait(@pid)
|
77
|
+
end
|
67
78
|
end
|
data/lib/restartable.rb
CHANGED
@@ -19,19 +19,17 @@ private
|
|
19
19
|
def run!
|
20
20
|
Signal.trap('INT') do
|
21
21
|
interrupt!
|
22
|
-
if @cpid
|
23
|
-
Process.kill('INT', -@cpid) rescue nil
|
24
|
-
end
|
22
|
+
signal_children!('INT') if @cpid
|
25
23
|
end
|
26
24
|
Signal.trap('TERM') do
|
27
25
|
terminate!
|
26
|
+
signal_children!('TERM') if @cpid
|
28
27
|
end
|
29
28
|
|
30
29
|
until @stop
|
31
30
|
@interrupted = nil
|
32
31
|
$stderr << "^C to restart, double ^C to stop\n".green
|
33
32
|
@cpid = fork do
|
34
|
-
Process.setpgrp
|
35
33
|
Signal.trap('INT', 'DEFAULT')
|
36
34
|
Signal.trap('TERM', 'DEFAULT')
|
37
35
|
@block.call
|
@@ -68,7 +66,7 @@ private
|
|
68
66
|
WAIT_SIGNALS.each do |time, signal|
|
69
67
|
sleep time
|
70
68
|
$stderr << "…SIG#{signal}…\n".yellow
|
71
|
-
|
69
|
+
signal_children!(signal)
|
72
70
|
end
|
73
71
|
end
|
74
72
|
Process.waitall
|
@@ -85,9 +83,19 @@ private
|
|
85
83
|
end
|
86
84
|
end
|
87
85
|
|
86
|
+
def signal_children!(signal)
|
87
|
+
children_pids.each do |pid|
|
88
|
+
begin
|
89
|
+
Process.kill(signal, pid)
|
90
|
+
rescue Errno::ESRCH
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
88
95
|
def children_pids
|
96
|
+
pgrp = Process.getpgrp
|
89
97
|
Sys::ProcTable.ps.select do |pe|
|
90
|
-
|
98
|
+
pgrp == case
|
91
99
|
when pe.respond_to?(:pgid)
|
92
100
|
pe.pgid
|
93
101
|
when pe.respond_to?(:pgrp)
|
@@ -97,6 +105,6 @@ private
|
|
97
105
|
else
|
98
106
|
raise 'Can\'t find process group id'
|
99
107
|
end
|
100
|
-
end.map(&:pid)
|
108
|
+
end.map(&:pid) - [$$]
|
101
109
|
end
|
102
110
|
end
|
data/restartable.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restartable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Kuchin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colored
|