runaway 1.0.0 → 1.0.1

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: f2394ae85e1bcf9ff2046d3892f33ece782e2e22
4
- data.tar.gz: 4838053519c1500f34bef114eb374a2b05af9833
3
+ metadata.gz: ee88a2e47d1bf2847893a4b258d236efcfff3fae
4
+ data.tar.gz: f3edef5cc5fae9363f1d56978c0465b56faa0a24
5
5
  SHA512:
6
- metadata.gz: 50c6402a8d00358139c9e93e37a02a4d34819e63ea6c7f00b27e6b544107af71d1a60b14671c2115c6d04565fe0d3a4f0310c2c79a3f100c453436f61b2e0a24
7
- data.tar.gz: 8555a4a081a964299e1866ee00bb0728984a87303add7f89b708a26429006f28721064d21bbe7e95dfd5f0a4106590de288a491e68e0796eb5170f87bad65f9a
6
+ metadata.gz: 0489708f0657aeb6e7b91c7f23e2007974d22577afe01b9c04b2dca6d12a9fcdbdf68cdbb965b75970351333eab45ec6a1599f3d34a3727abda9f8daa47ab248
7
+ data.tar.gz: 34eeca38ad28dfb7b205a40b9517f3b3123683a9fdd466031b848bd1780f9b67e1b477c3a1d10104b412b36ee80df21c33e1ab2dfcf5af799e0b0f86963d3ede
@@ -1,7 +1,7 @@
1
1
  require 'securerandom'
2
2
 
3
3
  module Runaway
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
 
6
6
  UncleanExit = Class.new(StandardError)
7
7
  Child = Class.new(StandardError)
@@ -49,9 +49,12 @@ module Runaway
49
49
  (Process.kill(sig, child_pid) rescue Errno::ESRCH) if !has_quit
50
50
  }
51
51
 
52
+ last_heartbeat_sent = started_at
52
53
  begin
53
54
  loop do
54
- sleep heartbeat_interval
55
+ sleep 0.5
56
+
57
+ break if has_quit
55
58
 
56
59
  # First check if it has exceeded it's wall clock time allowance
57
60
  running_for = Time.now - started_at
@@ -60,6 +63,11 @@ module Runaway
60
63
  child_pid, running_for, must_quit_within])
61
64
  end
62
65
 
66
+ # Then check if it is time to poke it with a heartbeat
67
+ at = Time.now
68
+ next if (at - last_heartbeat_sent) < heartbeat_interval
69
+ last_heartbeat_sent = at
70
+
63
71
  # Then send it the USR2 as a "ping", and expect a "pong" in
64
72
  # the form of a pipe write. If the pipe is still not readable
65
73
  # after a certain time, we assume the process has hung.
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: runaway 1.0.0 ruby lib
5
+ # stub: runaway 1.0.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "runaway"
9
- s.version = "1.0.0"
9
+ s.version = "1.0.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Julik Tarkhanov"]
14
- s.date = "2016-02-26"
14
+ s.date = "2016-03-01"
15
15
  s.description = "Spin off blocks in child processes and make sure they terminate on time"
16
16
  s.email = "me@julik.nl"
17
17
  s.extra_rdoc_files = [
@@ -17,15 +17,17 @@ describe "Runaway" do
17
17
  end
18
18
  end
19
19
 
20
- context 'with a process that sleeps for too long' do
20
+ context 'with a process that exceeds the maximum runtime' do
21
21
  it 'terminates the process' do
22
+ start_at = Time.now
22
23
  expect {
23
24
  Runaway.spin(must_quit_within: 3) do
24
- sleep 4
25
+ sleep 30
25
26
  end
26
27
  }.to raise_error {|err|
27
28
  expect(err).to be_kind_of(Runaway::RuntimeExceeded)
28
- expect(err.message).to match(/\d+ did not terminate after 4 secs \(limited to 3 secs\)/)
29
+ expect(err.message).to match(/\d+ did not terminate after \d+ secs \(limited to 3 secs\)/)
30
+ expect(Time.now - start_at).to be < 5 # Ensure it was killed quickly
29
31
  }
30
32
  end
31
33
  end
@@ -41,13 +43,26 @@ describe "Runaway" do
41
43
  end
42
44
  end
43
45
 
46
+ context 'when a process terminates before the first heartbeat has to be dispatched' do
47
+ it 'just returns :done' do
48
+ t = Time.now
49
+ return_token = Runaway.spin(heartbeat_interval: 5) { sleep 0.1 }
50
+ expect(return_token).to eq(:done)
51
+ delta = Time.now - t
52
+ expect(delta).to be < 2
53
+ end
54
+ end
55
+
44
56
  context 'when a process stops responding to heartbeats' do
45
- it 'raises an error' do
57
+ it 'kills it quickly and raises an error' do
58
+ t = Time.now
46
59
  expect {
47
- Runaway.spin { trap('USR2', 'DEFAULT'); trap('USR2') {}; sleep 7 }
60
+ # Delete, then override the USR2 trap so that heartbeats do not get handled at all
61
+ Runaway.spin(heartbeat_interval: 0.8) { trap('USR2', 'DEFAULT'); trap('USR2') {}; sleep 45 }
48
62
  }.to raise_error {|err|
49
63
  expect(err).to be_kind_of(Runaway::HeartbeatTimeout)
50
- expect(err.message).to match(/\d+ did not reply to heartbeat after 4 secs/)
64
+ expect(err.message).to match(/\d+ did not reply to heartbeat after \d+ secs/)
65
+ expect(Time.now - t).to be < 5 # should really ahve killed it fast
51
66
  }
52
67
  end
53
68
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runaway
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-26 00:00:00.000000000 Z
11
+ date: 2016-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec