terminator 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,10 +1,48 @@
1
1
  NAME
2
- terminator
2
+ Terminator
3
3
 
4
4
  SYNOPSIS
5
- an external timeout mechanism based on processes and signals. safe on
6
- windows. safe for system calls. safe for minors.
7
-
5
+ An external timeout mechanism based on processes and signals. Safe on
6
+ windows. Safe for system calls. Safe for minors. but not very safe
7
+ for misbehaving, downtrodden zombied out processes.
8
+
9
+ DESCRIPTION
10
+ Terminator is a solution to the problem of 'how am I meant to kill a
11
+ system call in Ruby!?'
12
+
13
+ Ruby (at least MRI) uses green threads to "multitask". This means that
14
+ there is really only ever one ruby process running which then splits up
15
+ it's processor time between all of it's threads internally.
16
+
17
+ The processor then only has to deal with one ruby process and the ruby
18
+ process deals with all it's threads. There are pros and cons to this
19
+ method, but that is not the point of this library.
20
+
21
+ The point is, that if you make a system call to an external resource from
22
+ ruby, then the kernel will go and make that call for ruby and NOT COME BACK
23
+ to ruby until that system call completes or fails. This can take a very
24
+ long time and is why your feeble attempts at using ruby's internal "Timeout"
25
+ command has failed miserably at timing out your external web service, database
26
+ or network connections.
27
+
28
+ You see, Ruby just doesn't get a chance to do anything as the kernel goes
29
+ "I'm not going to talk to you again until your system calls complete". Sort
30
+ of a no win situation for Ruby.
31
+
32
+ That's where Terminator comes in. Like Arnie, he will come back. No matter
33
+ what, and complete his mission, unless he gets aborted before his timeout,
34
+ you can trust Terminator to thoroughly and without remorse, nuke your
35
+ misbehaving and timing out ruby processes efficiently, and quickly.
36
+
37
+ HOW IT WORKS
38
+ Basically we create a new terminator ruby process, separate to the existing
39
+ running ruby process that has a simple command of sleep for x seconds, and then
40
+ do a process TERM on the PID of the original ruby process that created it.
41
+
42
+ If your process finishes before the timeout, it will kill the Terminator first.
43
+
44
+ So really it is a race of who is going to win?
45
+
8
46
  INSTALL
9
47
  gem install terminator
10
48
 
@@ -14,7 +52,7 @@ URIS
14
52
 
15
53
  HISTORY
16
54
  0.4.2
17
- initial version with
55
+ initial version
18
56
 
19
57
  AUTHORS
20
58
  ara.t.howard - ara.t.howard@gmail.com
data/gemspec.rb CHANGED
File without changes
File without changes
data/install.rb CHANGED
File without changes
@@ -4,13 +4,16 @@ require 'tempfile'
4
4
  require 'fattr'
5
5
 
6
6
  module Terminator
7
- Version = '0.4.2'
7
+ Version = '0.4.3'
8
8
 
9
9
  def terminate options = {}, &block
10
- options = { :seconds => Float(options).to_i } unless Hash === options
10
+ options = { :seconds => Float(options).to_f } unless Hash === options
11
11
 
12
12
  seconds = getopt :seconds, options
13
- trap = getopt :trap, options, lambda{ eval("raise(::Terminator::Error, '#{ seconds }s')", block) }
13
+
14
+ raise ::Terminator::Error, "Time to kill must be greater than 0" unless seconds > 0
15
+
16
+ trap = getopt :trap, options, lambda{ eval("raise(::Terminator::Error, 'Timeout out after #{ seconds }s')", block) }
14
17
 
15
18
  handler = Signal.trap(signal, &trap)
16
19
 
@@ -0,0 +1,135 @@
1
+ #! /usr/bin/env bacon
2
+
3
+ require 'rubygems'
4
+ require 'bacon'
5
+
6
+ alias :doing :lambda
7
+
8
+ describe Terminator do
9
+
10
+ describe "being given a contract to terminate" do
11
+ it "should not complain about it" do
12
+ doing { Terminator.terminate(1) { "Hello" } }.should_not raise_error
13
+ end
14
+
15
+ it "should not accept an expired contract" do
16
+ doing { Terminator.terminate(0) { "Hello" } }.should.raise(Terminator::Error)
17
+ end
18
+
19
+ it "should not accept a late contract" do
20
+ doing { Terminator.terminate(-0.1) { "Hello" } }.should.raise(Terminator::Error)
21
+ end
22
+
23
+ it "should handle fractions of seconts" do
24
+ failed = false
25
+ Terminator.terminate(0.3) do
26
+ failed = true
27
+ end
28
+ failed.should.be.false
29
+ end
30
+
31
+ end
32
+
33
+ describe "handling contracts" do
34
+ it "should not kill it's mark if the mark completes" do
35
+ failed = false
36
+ Terminator.terminate(0.01) do
37
+ failed = true
38
+ end
39
+ failed.should.be.false
40
+ end
41
+
42
+ it "should not terminate it's mark until the time is up" do
43
+ failed = false
44
+ Terminator.terminate(1) do
45
+ sleep 0.9
46
+ failed = true
47
+ end
48
+ failed.should.be.false
49
+ end
50
+
51
+ it "should handle multiple overlapping contracts gracefully" do
52
+ first_job = false
53
+ second_job = false
54
+ third_job = false
55
+
56
+ Terminator.terminate(0.3) do
57
+ first_job = true
58
+ end
59
+
60
+ Terminator.terminate(0.3) do
61
+ second_job = true
62
+ end
63
+
64
+ Terminator.terminate(0.3) do
65
+ third_job = true
66
+ end
67
+
68
+ first_job.should.be.true
69
+ second_job.should.be.true
70
+ third_job.should.be.true
71
+ end
72
+
73
+ it "should be a surgical weapon only selectively destroying it's marks" do
74
+ first_job = false
75
+ second_job = false
76
+
77
+ begin
78
+ Terminator.terminate(0.3) do
79
+ sleep 0.4
80
+ first_job = true
81
+ end
82
+ rescue
83
+ nil
84
+ end
85
+
86
+ Terminator.terminate(0.3) do
87
+ second_job = true
88
+ end
89
+
90
+ first_job.should.be.false
91
+ second_job.should.be.true
92
+ end
93
+
94
+ it "should a surgical weapon only selectively destroying it's marks - backwards" do
95
+ first_job = false
96
+ second_job = false
97
+
98
+ Terminator.terminate(0.3) do
99
+ first_job = true
100
+ end
101
+
102
+ begin
103
+ Terminator.terminate(0.3) do
104
+ sleep 0.4
105
+ second_job = true
106
+ end
107
+ rescue
108
+ nil
109
+ end
110
+
111
+ first_job.should.be.true
112
+ second_job.should.be.false
113
+
114
+ end
115
+
116
+ it "should accept an optional trap handler" do
117
+ trap = lambda{ 'You failed me again!' }
118
+
119
+ doing {
120
+ Terminator.terminate(0.001, :trap => trap) do
121
+ sleep 0.2
122
+ job = true
123
+ end }.should.raise(Terminator::Error)
124
+
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+
131
+ BEGIN {
132
+ rootdir = File.split(File.expand_path(File.dirname(File.dirname(__FILE__))))
133
+ libdir = File.join(rootdir, 'lib')
134
+ require File.join(libdir, 'terminator')
135
+ }
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ara T. Howard
@@ -9,12 +9,11 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-09-10 00:00:00 -06:00
12
+ date: 2008-09-11 00:00:00 +10:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fattr
17
- type: :runtime
18
17
  version_requirement:
19
18
  version_requirements: !ruby/object:Gem::Requirement
20
19
  requirements:
@@ -43,7 +42,8 @@ files:
43
42
  - samples/c.rb
44
43
  - samples/d.rb
45
44
  - spec
46
- - spec/terminator.rb
45
+ - spec/terminator_spec.rb
46
+ - terminator-0.4.2.gem
47
47
  has_rdoc: false
48
48
  homepage: http://codeforpeople.com/lib/ruby/terminator/
49
49
  post_install_message:
@@ -66,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
66
  requirements: []
67
67
 
68
68
  rubyforge_project: codeforpeople
69
- rubygems_version: 1.2.0
69
+ rubygems_version: 1.0.1
70
70
  signing_key:
71
71
  specification_version: 2
72
72
  summary: terminator
@@ -1,16 +0,0 @@
1
- #! /usr/bin/env bacon
2
-
3
- require 'rubygems'
4
- require 'bacon'
5
-
6
- describe Terminator do
7
- it 'should have some tests' do
8
- 0b101010.should == 42
9
- end
10
- end
11
-
12
- BEGIN {
13
- rootdir = File.split(File.expand_path(File.dirname(File.dirname(__FILE__))))
14
- libdir = File.join(rootdir, 'lib')
15
- require File.join(libdir, 'terminator')
16
- }