timeout-interrupt 0.1.1 → 0.2.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.
- data/README.md +54 -1
- data/VERSION +1 -1
- data/lib/timeout_interrupt.rb +56 -32
- data/test/test_ruby-timeout-interrupt.rb +115 -40
- data/timeout-interrupt.gemspec +68 -0
- metadata +18 -17
data/README.md
CHANGED
@@ -7,9 +7,62 @@ It uses POSIX's alarm and traps ALRM-signals.
|
|
7
7
|
|
8
8
|
Known limitations bacause of alarm and ALRM are, that you can not use alarm or trap ALRM.
|
9
9
|
|
10
|
+
Scopes
|
11
|
+
======
|
12
|
+
|
13
|
+
If you need scopes with inner and outer time outs, you should know:
|
14
|
+
|
15
|
+
The first timed out Timeout will be raised:
|
16
|
+
|
17
|
+
include TimeoutInterrupt
|
18
|
+
timeout(1) { # Will be raised
|
19
|
+
timeout(10) { sleep 2 } # Will not be raised
|
20
|
+
}
|
21
|
+
|
22
|
+
If you want to know, which was raised, you need custom exceptions:
|
23
|
+
|
24
|
+
class CustomErrorWillBeRaised <Exception
|
25
|
+
end
|
26
|
+
class CustomErrorNotRaise <Exception
|
27
|
+
end
|
28
|
+
include TimeoutInterrupt
|
29
|
+
timeout( 1, CustomErrorWillBeRaised) { # Will be raised again
|
30
|
+
timeout( 10, CustomErrorNotRaise) { sleep 2 } # Will not be raised
|
31
|
+
}
|
32
|
+
|
33
|
+
Problems
|
34
|
+
========
|
35
|
+
|
36
|
+
Memory-Leaks or no clean up
|
37
|
+
---------------------------
|
38
|
+
|
10
39
|
Do not forget, syscall can have allocated memory.
|
11
40
|
If you interrupt a call, which can not free his allocations, you will have a memory leak.
|
12
|
-
|
41
|
+
If it opens a file, reads it and closes it and while it reads, a time out occurs, the file will not be closed.
|
42
|
+
|
43
|
+
So, use it only, if your process did not live any longer or if you call something, which never allocate mem or opens a file.
|
44
|
+
|
45
|
+
Every time, a process dies, all his memory will be freed and every file will be closed, so let your process die and you should be safe.
|
46
|
+
|
47
|
+
Exception-handling
|
48
|
+
------------------
|
49
|
+
|
50
|
+
Timeouts can break your exception-handling! You should not handling exception while you wait for a timeout:
|
51
|
+
|
52
|
+
include TimeoutInterrupt
|
53
|
+
timeout(1) {
|
54
|
+
begin
|
55
|
+
transaction_begin
|
56
|
+
do_something
|
57
|
+
ensure
|
58
|
+
clean_up
|
59
|
+
transaction_end
|
60
|
+
end
|
61
|
+
}
|
62
|
+
|
63
|
+
Same happens, if clean\_up will raise an exception.
|
64
|
+
|
65
|
+
And same problem you have with ruby's `Timeout.timeout`.
|
13
66
|
|
14
67
|
Copyleft
|
15
68
|
=========
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/timeout_interrupt.rb
CHANGED
@@ -7,43 +7,67 @@ module FFI
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
module
|
11
|
-
|
12
|
-
|
10
|
+
module TimeoutInterruptSingleton
|
11
|
+
class <<self
|
12
|
+
def timeouts thread = nil
|
13
|
+
@timeouts ||= Hash.new {|h,k| h[k] = [] }
|
14
|
+
thread = Thread.current if thread.kind_of? Thread
|
15
|
+
thread ? @timeouts[thread] : @timeouts
|
16
|
+
end
|
17
|
+
|
18
|
+
def alarm_trap sig
|
19
|
+
key, (at, bt, exception) = self.timeouts.min_by {|key,(at,bt,ex)| at }
|
20
|
+
return if Time.now < at
|
21
|
+
raise exception, 'execution expired', bt
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup
|
25
|
+
if timeouts.empty?
|
26
|
+
Signal.trap( 'ALRM') {}
|
27
|
+
FFI::LibC.alarm 0
|
28
|
+
else
|
29
|
+
key, (at, bt) = timeouts.min_by {|key,(at,bt)| at }
|
30
|
+
secs = (at - Time.now)
|
31
|
+
alarm_trap 14 if 0 > secs
|
32
|
+
Signal.trap 'ALRM', &method( :alarm_trap)
|
33
|
+
FFI::LibC.alarm secs.to_i+1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def timeout seconds = nil, exception = nil
|
38
|
+
return setup if seconds.nil?
|
39
|
+
seconds = seconds.to_i
|
40
|
+
exception ||= TimeoutInterrupt::Error
|
41
|
+
raise exception, "Timeout must be longer than '0' seconds." unless 0 < seconds
|
42
|
+
unless block_given?
|
43
|
+
return lambda {|&e|
|
44
|
+
raise exception, "Expect a lambda." unless e
|
45
|
+
timeout seconds, exception, &e
|
46
|
+
}
|
47
|
+
end
|
48
|
+
at = Time.now + seconds
|
49
|
+
key, bt = Random.rand( 2**64-1), Kernel.caller
|
50
|
+
begin
|
51
|
+
self.timeouts[key] = [at, bt, exception]
|
52
|
+
setup
|
53
|
+
yield
|
54
|
+
ensure
|
55
|
+
self.timeouts.delete key
|
56
|
+
setup
|
57
|
+
end
|
58
|
+
end
|
13
59
|
end
|
60
|
+
end
|
14
61
|
|
15
|
-
|
16
|
-
|
17
|
-
return if Time.now < at
|
18
|
-
raise Timeout::Error, 'execution expired', bt
|
62
|
+
module TimeoutInterrupt
|
63
|
+
class Error < Timeout::Error
|
19
64
|
end
|
20
65
|
|
21
|
-
def self.
|
22
|
-
|
23
|
-
Signal.trap( 'ALRM') {}
|
24
|
-
FFI::LibC.alarm 0
|
25
|
-
else
|
26
|
-
key, (at, bt) = TimeoutInterrupt.timeouts.min_by {|key,(at,bt)| at }
|
27
|
-
secs = (at - Time.now).to_i+1
|
28
|
-
TimeoutInterrupt.alarm_trap if 1 > secs
|
29
|
-
Signal.trap 'ALRM', &TimeoutInterrupt.method( :alarm_trap)
|
30
|
-
FFI::LibC.alarm secs
|
31
|
-
end
|
66
|
+
def self.timeout seconds = nil, exception = nil, &e
|
67
|
+
TimeoutInterruptSingleton.timeout seconds, exception, &e
|
32
68
|
end
|
33
69
|
|
34
|
-
def
|
35
|
-
seconds
|
36
|
-
raise Timeout::Error, "Timeout must be longer than '0' seconds." unless 0 < seconds
|
37
|
-
return lambda {|&e| self.timeout seconds, &e } unless block_given?
|
38
|
-
at = Time.now + seconds
|
39
|
-
key, bt = Random.rand( 2**64-1), Kernel.caller
|
40
|
-
begin
|
41
|
-
TimeoutInterrupt.timeouts[key] = [at, bt]
|
42
|
-
TimeoutInterrupt.setup_timeout
|
43
|
-
yield
|
44
|
-
ensure
|
45
|
-
TimeoutInterrupt.timeouts.delete key
|
46
|
-
TimeoutInterrupt.setup_timeout
|
47
|
-
end
|
70
|
+
def timeout seconds = nil, exception = nil, &e
|
71
|
+
TimeoutInterruptSingleton.timeout seconds, exception, &e
|
48
72
|
end
|
49
73
|
end
|
@@ -11,70 +11,145 @@ class TestRubyTimeoutInterrupt < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def assert_no_defined_timeout_yet
|
14
|
-
assert
|
14
|
+
assert TimeoutInterruptSingleton.timeouts.empty?, "For testing, no timeout should be defined, yet!"
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
def print_timeouts pre
|
18
|
+
puts "#{pre}: < #{TimeoutInterruptSingleton.timeouts.map {|k,(a,_b,_e)| "#{k.inspect}: #{a.strftime '%H:%M:%S'} (#{a-Time.now})" }.join ', '} >"
|
19
|
+
end
|
20
|
+
|
21
|
+
# For testing raising scoped Timeout.
|
22
|
+
class TimeoutError < Exception
|
23
|
+
end
|
24
|
+
# For testing raising scoped TimeoutInterrupt.
|
25
|
+
class TimeoutInterruptError < Exception
|
26
|
+
end
|
27
|
+
|
28
|
+
context "Long really blocking calls" do
|
29
|
+
should "not be interrupted by the old Timeout" do
|
30
|
+
time = Benchmark.realtime do
|
31
|
+
assert_nothing_raised TimeoutError, "Unexpected time out. Your Ruby implementation can time out with old Timeout? You need not TimeoutInterrupt. But it is ok. You can ignore this Error. :)" do
|
32
|
+
assert_raise TimeoutInterruptError, "Ohoh. TimeoutInterrupt should be raised." do
|
33
|
+
TimeoutInterrupt.timeout 5, TimeoutInterruptError do
|
34
|
+
Timeout.timeout 1, TimeoutError do
|
35
|
+
blocking
|
36
|
+
assert false, "Should be unreachable!"
|
37
|
+
end
|
38
|
+
end
|
24
39
|
end
|
25
40
|
end
|
26
|
-
rescue Timeout::Error
|
27
|
-
:ok
|
28
41
|
end
|
42
|
+
assert 3 < time, "Did timeout!"
|
29
43
|
end
|
30
|
-
assert 3 < time, "Did timeout!"
|
31
|
-
end
|
32
44
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
45
|
+
should "be interrupted by the new TimeoutInterrupt" do
|
46
|
+
time = Benchmark.realtime do
|
47
|
+
assert_raise TimeoutInterrupt::Error, "It should be timed out, why it did not raise TimeoutInterrupt::Error?" do
|
48
|
+
TimeoutInterrupt.timeout 1 do
|
49
|
+
blocking
|
50
|
+
assert false, "Should be unreachable!"
|
51
|
+
end
|
39
52
|
end
|
40
|
-
rescue Timeout::Error
|
41
|
-
:ok
|
42
53
|
end
|
54
|
+
assert 3 > time, "Did not interrupt."
|
43
55
|
end
|
44
|
-
assert 3 > time, "Did not interrupt."
|
45
56
|
end
|
46
57
|
|
47
|
-
should "interrupt scoped timeout, but not outer timeout" do
|
58
|
+
should "interrupt scoped timeout, but not time out the outer timeout" do
|
48
59
|
assert_no_defined_timeout_yet
|
49
|
-
|
50
|
-
|
51
|
-
TimeoutInterrupt.timeout
|
52
|
-
|
60
|
+
assert_raise TimeoutInterruptError, "It should be timed out, why it did not raise TimeoutInterruptError?" do
|
61
|
+
assert_nothing_raised Timeout::Error, "Oh, outer timeout was timed out. Your machine must be slow, or there is a bug" do
|
62
|
+
TimeoutInterrupt.timeout 10 do
|
63
|
+
TimeoutInterrupt.timeout 1, TimeoutInterruptError do
|
64
|
+
Kernel.sleep 2
|
65
|
+
end
|
66
|
+
assert false, "Should be unreachable!"
|
53
67
|
end
|
54
|
-
assert false, "Should be unreachable!"
|
55
68
|
end
|
56
|
-
rescue Timeout::Error
|
57
|
-
:ok
|
58
69
|
end
|
59
|
-
assert
|
70
|
+
assert TimeoutInterruptSingleton.timeouts.empty?, "There are timeouts defined, yet!"
|
60
71
|
end
|
61
72
|
|
62
73
|
should "clear timeouts, if not timed out, too." do
|
63
74
|
assert_no_defined_timeout_yet
|
64
75
|
TimeoutInterrupt.timeout(10) {}
|
65
|
-
assert
|
76
|
+
assert TimeoutInterruptSingleton.timeouts.empty?, "There are timeouts defined, yet!"
|
66
77
|
end
|
67
78
|
|
68
|
-
|
69
|
-
assert_no_defined_timeout_yet
|
70
|
-
assert TimeoutInterrupt.timeout(10).kind_of?( Proc), "Did not return a Proc."
|
79
|
+
class CustomException <Exception
|
71
80
|
end
|
72
81
|
|
73
|
-
should "
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
82
|
+
should "raise custom exception." do
|
83
|
+
assert_raise CustomException, "Custom exceptions do not work." do
|
84
|
+
TimeoutInterrupt.timeout 1, CustomException do
|
85
|
+
sleep 2
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "A prepared timeout (Proc)" do
|
91
|
+
should "be returned by calling timeout without a block" do
|
92
|
+
assert_no_defined_timeout_yet
|
93
|
+
assert TimeoutInterrupt.timeout(10).kind_of?( Proc), "Did not return a Proc."
|
94
|
+
end
|
95
|
+
|
96
|
+
should "run with once given timeout" do
|
97
|
+
assert_no_defined_timeout_yet
|
98
|
+
to = TimeoutInterrupt.timeout 10
|
99
|
+
called = false
|
100
|
+
to.call { called = true }
|
101
|
+
assert called, "Did not called."
|
102
|
+
end
|
103
|
+
|
104
|
+
should "raise custom exception" do
|
105
|
+
assert_raise CustomException, "Custom exceptions do not work." do
|
106
|
+
prepared = TimeoutInterrupt.timeout 1, CustomException
|
107
|
+
prepared.call { sleep 2 }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
should "not be scopeable, without manualy setup after rescue and 2 time outs at once" do
|
112
|
+
prepared = TimeoutInterrupt.timeout 1
|
113
|
+
assert_no_defined_timeout_yet
|
114
|
+
called = false
|
115
|
+
prepared.call do
|
116
|
+
assert_raise TimeoutInterrupt::Error, 'It should time out after one second, but it did not.' do
|
117
|
+
prepared.call { 2; sleep 2 }
|
118
|
+
end
|
119
|
+
called = true
|
120
|
+
end
|
121
|
+
assert called, "It's true, it should be called, also if not expected."
|
122
|
+
end
|
123
|
+
|
124
|
+
should "be scopeable, with manualy setup after rescue, also if 2 time outs at once." do
|
125
|
+
prepared = TimeoutInterrupt.timeout 1
|
126
|
+
assert_no_defined_timeout_yet
|
127
|
+
prepared.call do
|
128
|
+
assert_raise TimeoutInterrupt::Error, 'It should time out after one second, but it did not.' do
|
129
|
+
prepared.call { sleep 2 }
|
130
|
+
end
|
131
|
+
assert_raise TimeoutInterrupt::Error, 'Manualy called timeout setup did not raise.' do
|
132
|
+
TimeoutInterrupt.timeout
|
133
|
+
end
|
134
|
+
assert true, "Should never be reached."
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class IncludeModuleTest
|
140
|
+
include TimeoutInterrupt
|
141
|
+
def please_timeout after
|
142
|
+
timeout after do
|
143
|
+
sleep after+10
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "Included module" do
|
149
|
+
should "provide timeout too" do
|
150
|
+
assert_raise TimeoutInterrupt::Error, "Included timeout can not be used?" do
|
151
|
+
IncludeModuleTest.new.please_timeout 2
|
152
|
+
end
|
153
|
+
end
|
79
154
|
end
|
80
155
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "timeout-interrupt"
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Denis Knauf"]
|
12
|
+
s.date = "2013-03-07"
|
13
|
+
s.description = "Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm."
|
14
|
+
s.email = "Denis.Knauf@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/timeout_interrupt.rb",
|
28
|
+
"test/helper.rb",
|
29
|
+
"test/test_ruby-timeout-interrupt.rb",
|
30
|
+
"timeout-interrupt.gemspec"
|
31
|
+
]
|
32
|
+
s.homepage = "http://github.com/DenisKnauf/ruby-timeout-interrupt"
|
33
|
+
s.licenses = ["AGPLv3"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubygems_version = "1.8.11"
|
36
|
+
s.summary = "\"Interrupts systemcalls too.\""
|
37
|
+
|
38
|
+
if s.respond_to? :specification_version then
|
39
|
+
s.specification_version = 3
|
40
|
+
|
41
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
42
|
+
s.add_runtime_dependency(%q<ffi-libc>, [">= 0"])
|
43
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
44
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
45
|
+
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
46
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
47
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
49
|
+
else
|
50
|
+
s.add_dependency(%q<ffi-libc>, [">= 0"])
|
51
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
52
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
53
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
54
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
55
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
56
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
57
|
+
end
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<ffi-libc>, [">= 0"])
|
60
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
61
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
62
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
63
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
64
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
65
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timeout-interrupt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi-libc
|
16
|
-
requirement: &
|
16
|
+
requirement: &79897400 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *79897400
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: shoulda
|
27
|
-
requirement: &
|
27
|
+
requirement: &79918180 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *79918180
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: yard
|
38
|
-
requirement: &
|
38
|
+
requirement: &79914220 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *79914220
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rdoc
|
49
|
-
requirement: &
|
49
|
+
requirement: &79910520 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *79910520
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: bundler
|
60
|
-
requirement: &
|
60
|
+
requirement: &79907200 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *79907200
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: jeweler
|
71
|
-
requirement: &
|
71
|
+
requirement: &79905270 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *79905270
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: simplecov
|
82
|
-
requirement: &
|
82
|
+
requirement: &79904230 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *79904230
|
91
91
|
description: Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm.
|
92
92
|
email: Denis.Knauf@gmail.com
|
93
93
|
executables: []
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/timeout_interrupt.rb
|
107
107
|
- test/helper.rb
|
108
108
|
- test/test_ruby-timeout-interrupt.rb
|
109
|
+
- timeout-interrupt.gemspec
|
109
110
|
homepage: http://github.com/DenisKnauf/ruby-timeout-interrupt
|
110
111
|
licenses:
|
111
112
|
- AGPLv3
|
@@ -121,7 +122,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
122
|
version: '0'
|
122
123
|
segments:
|
123
124
|
- 0
|
124
|
-
hash: -
|
125
|
+
hash: -567688307
|
125
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
127
|
none: false
|
127
128
|
requirements:
|