multi_timeout 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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