multi_timeout 1.0.3 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f1f460fe210454f8a142a9e7ee4d4cf521263d8
4
- data.tar.gz: 3fb809959c3166c36b2eb4e3bc1980bfb788941d
3
+ metadata.gz: 1f73598e7b2cfe2ee52aa0b1ca2382b0f43bc21b
4
+ data.tar.gz: bd63e10e7651ac2029614095c0e82565876d8c8e
5
5
  SHA512:
6
- metadata.gz: 684524c40cb2667334c683fe4282a4bb9b03bddc3ad37fd5f5552b5eb0485d12366b2dcd071357e802d8986646795762ed13f2366c87e3c73c685cc475d17257
7
- data.tar.gz: 5bbc4da08af8baa9de7c69ed7ec924bce96ab73fe4cbdb6e34f5bd6a5dbdc32ae280c84d1ad6a8d1cc5419d4128756dac4baf882603d19c4faa26744ca2f3eac
6
+ metadata.gz: 2d7bf1f3e6b09e6cc2bf5f3b9f2072e7e20401e0cb748ad8149821a3b525e7f46d307620aa840224e802f12593826d90a2ba090100c5dfd96608fb946b0610ad
7
+ data.tar.gz: 8b24614fcbf784f82473ab3bde7db719d0bb8ca2056beab592c1ac4579c79145d88848b1b996a247f4f2d53447a2774b1d8e611e977cc424afaf9474bf1bc319
@@ -1,60 +1,64 @@
1
1
  require "multi_timeout/version"
2
- require "shellwords"
3
2
  require "optparse"
4
3
 
5
4
  module MultiTimeout
6
- module CLI
7
- TICK = 1
8
- VALID_SIGNAL = /^(-(\d+|[A-Z\d]+))$/
9
-
10
- class << self
11
- def run(argv)
12
- options = parse_options(argv)
13
- command = options[:command]
14
-
15
- pid = Process.spawn command, :pgroup => true
16
- gid = Process.getpgid(pid)
17
- Thread.new do
18
- now = 0
19
- loop do
20
- break if dead?(pid)
21
-
22
- options[:timeouts].each do |signal, t|
23
- if now >= t
24
- options[:timeouts].delete([signal, t])
25
- puts "Killing '#{truncate(command, 30)}' with signal #{signal} after #{now} seconds"
26
- Process.kill(signal, -gid)
27
- end
5
+ TICK = 1
6
+ VALID_SIGNAL = /^(-(\d+|[A-Z\d]+))$/
7
+
8
+ class << self
9
+ def run(command, timeouts: nil)
10
+ # spawn process in a separate group so we can take it down completely and not leave any children
11
+ pid = Process.spawn({}, *command, pgroup: true)
12
+ gid = Process.getpgid(pid)
13
+
14
+ Thread.new do
15
+ elapsed = 0
16
+ loop do
17
+ break if dead?(pid)
18
+
19
+ timeouts.each do |signal, max|
20
+ if elapsed >= max
21
+ timeouts.delete(signal)
22
+ puts "Killing '#{truncate(Array(command).join(" "), 30)}' with signal #{signal} after #{elapsed} seconds"
23
+ Process.kill(signal, -gid)
28
24
  end
29
- now += TICK
30
- sleep TICK
31
25
  end
26
+ elapsed += TICK
27
+ sleep TICK
32
28
  end
33
-
34
- Process.wait2.last.exitstatus || 1
35
29
  end
36
30
 
37
- private
31
+ Process.wait2(pid).last.exitstatus || 1
32
+ end
38
33
 
39
- def truncate(string, count)
40
- if string.size > count
41
- string.slice(0, count-3) + "..."
42
- else
43
- string
44
- end
34
+ private
35
+
36
+ def truncate(string, count)
37
+ if string.size > count
38
+ string.slice(0, count-3) + "..."
39
+ else
40
+ string
45
41
  end
42
+ end
46
43
 
47
- def dead?(pid)
48
- Process.getpgid(pid)
49
- false
50
- rescue Errno::ESRCH
51
- true
44
+ def dead?(pid)
45
+ Process.getpgid(pid)
46
+ false
47
+ rescue Errno::ESRCH
48
+ true
49
+ end
50
+ end
51
+
52
+ module CLI
53
+ class << self
54
+ def run(argv)
55
+ MultiTimeout.run(*parse_options(argv))
52
56
  end
53
57
 
54
58
  def parse_options(argv)
55
59
  options = {:timeouts => []}
56
60
  options[:timeouts], argv = consume_signals(argv)
57
- options[:command], argv = consume_command(argv)
61
+ command, argv = consume_command(argv)
58
62
 
59
63
  OptionParser.new do |opts|
60
64
  opts.banner = <<-BANNER.gsub(/^ {10}/, "")
@@ -72,7 +76,7 @@ module MultiTimeout
72
76
 
73
77
  raise "No timeouts given" if options[:timeouts].empty?
74
78
 
75
- options
79
+ [command, options]
76
80
  end
77
81
 
78
82
  def consume_command(argv)
@@ -81,11 +85,11 @@ module MultiTimeout
81
85
  while argv.first =~ /^-/
82
86
  options << argv.shift
83
87
  end
84
- return Shellwords.shelljoin(argv), options
88
+ return argv, options
85
89
  end
86
90
 
87
91
  def consume_signals(argv)
88
- timeouts = []
92
+ timeouts = {}
89
93
  signal = nil
90
94
  argv = argv.map do |item|
91
95
  if !signal && item =~ VALID_SIGNAL
@@ -94,7 +98,7 @@ module MultiTimeout
94
98
  elsif signal
95
99
  signal = signal.sub("-", "")
96
100
  signal = signal.to_i if signal =~ /^\d+$/
97
- timeouts << [signal, item.to_i * multi(item)]
101
+ timeouts[signal] = human_value_to_seconds(item)
98
102
  signal = nil
99
103
  next
100
104
  else
@@ -105,15 +109,16 @@ module MultiTimeout
105
109
  return timeouts, argv
106
110
  end
107
111
 
108
- def multi(t)
109
- case t
110
- when /^\d+s$/ then 1
111
- when /^\d+m$/ then 60
112
- when /^\d+h$/ then 60 * 60
113
- when /^\d+$/ then 1
114
- else
115
- raise "Unknown format for time #{t}"
116
- end
112
+ def human_value_to_seconds(t)
113
+ unit =
114
+ case t
115
+ when /^\d+s$/ then 1
116
+ when /^\d+m$/ then 60
117
+ when /^\d+h$/ then 60 * 60
118
+ when /^\d+$/ then 1
119
+ else raise "Unknown format for time #{t}"
120
+ end
121
+ t.to_i * unit
117
122
  end
118
123
  end
119
124
  end
@@ -1,3 +1,3 @@
1
1
  module MultiTimeout
2
- VERSION = "1.0.3"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,36 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_timeout
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain:
11
- - |
12
- -----BEGIN CERTIFICATE-----
13
- MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MRAwDgYDVQQDDAdtaWNo
14
- YWVsMRcwFQYKCZImiZPyLGQBGRYHZ3Jvc3NlcjESMBAGCgmSJomT8ixkARkWAml0
15
- MB4XDTE0MDIwNDIwMjk0MVoXDTE1MDIwNDIwMjk0MVowPzEQMA4GA1UEAwwHbWlj
16
- aGFlbDEXMBUGCgmSJomT8ixkARkWB2dyb3NzZXIxEjAQBgoJkiaJk/IsZAEZFgJp
17
- dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMorXo/hgbUq97+kII9H
18
- MsQcLdC/7wQ1ZP2OshVHPkeP0qH8MBHGg6eYisOX2ubNagF9YTCZWnhrdKrwpLOO
19
- cPLaZbjUjljJ3cQR3B8Yn1veV5IhG86QseTBjymzJWsLpqJ1UZGpfB9tXcsFtuxO
20
- 6vHvcIHdzvc/OUkICttLbH+1qb6rsHUceqh+JrH4GrsJ5H4hAfIdyS2XMK7YRKbh
21
- h+IBu6dFWJJByzFsYmV1PDXln3UBmgAt65cmCu4qPfThioCGDzbSJrGDGLmw/pFX
22
- FPpVCm1zgYSb1v6Qnf3cgXa2f2wYGm17+zAVyIDpwryFru9yF/jJxE38z/DRsd9R
23
- /88CAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFLIj
24
- Z1x7SnjGGHK+MiVZkFjjS/iMMB0GA1UdEQQWMBSBEm1pY2hhZWxAZ3Jvc3Nlci5p
25
- dDAdBgNVHRIEFjAUgRJtaWNoYWVsQGdyb3NzZXIuaXQwDQYJKoZIhvcNAQEFBQAD
26
- ggEBAExBcUWfGuamYn+IddOA0Ws8jUKwB14RXoZRDrTiTAlMm3Bkg2OKyxS3uJXa
27
- 6Z+LwFiZwVYk62yHXqNzEJycQk4SEmY+xDWLj0p7X6qEeU4QZKwR1TwJ5z3PTrZ6
28
- irJgM3q7NIBRvmTzRaAghWcQn+Eyr5YLOfMksjVBMUMnzh5/ZDgq53LphgJbGwvz
29
- ScJAgfNclLHnjk9q1mT1s0e1FPWbiAL3siBIR5HpH8qtSEiivTf2ntciebOqS93f
30
- F5etKHZg0j3eHO31/i2HnswY04lqGImUu6aM5EnijFTB7PPW2KwKKM4+kKDYFdlw
31
- /0WV1Ng2/Y6qsHwmqGg2VlYj2h4=
32
- -----END CERTIFICATE-----
33
- date: 2014-03-12 00:00:00.000000000 Z
10
+ cert_chain: []
11
+ date: 2016-09-19 00:00:00.000000000 Z
34
12
  dependencies: []
35
13
  description:
36
14
  email: michael@grosser.it
@@ -53,17 +31,17 @@ require_paths:
53
31
  - lib
54
32
  required_ruby_version: !ruby/object:Gem::Requirement
55
33
  requirements:
56
- - - '>='
34
+ - - ">="
57
35
  - !ruby/object:Gem::Version
58
- version: 1.9.3
36
+ version: 2.0.0
59
37
  required_rubygems_version: !ruby/object:Gem::Requirement
60
38
  requirements:
61
- - - '>='
39
+ - - ">="
62
40
  - !ruby/object:Gem::Version
63
41
  version: '0'
64
42
  requirements: []
65
43
  rubyforge_project:
66
- rubygems_version: 2.0.14
44
+ rubygems_version: 2.5.1
67
45
  signing_key:
68
46
  specification_version: 4
69
47
  summary: Use multiple timeouts to soft and then hard kill a command
Binary file
data.tar.gz.sig DELETED
@@ -1 +0,0 @@
1
- �K�r%H��w|.1�S�'6�_��-�$_e�� &����W������gH���� �F{�Gk� �����@�������1��-� ������*�Ğ%#P�wX �m�lx�w���х��[���FD����g�Z��\ �O–��X��?���:�V�Vڒ�z��bdİYE�N�x�����M���EP08gU��S��.�B3��� ���I�N�tk���[rY�a/T��ۦ��s��* ��9�o�T_Ԅ
metadata.gz.sig DELETED
Binary file