itimer 8 → 9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/lib/itimer.rb +41 -30
  4. data/test/itimer.rb +13 -6
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: df5173d93aec0faedb0a3686f8c9509c7c1b9359
4
- data.tar.gz: 7ebb17e6857fcbe7ed386f42b09a504da53d4398
3
+ metadata.gz: 5b571dc4407cd0e99f440b372bc6ac65238471ab
4
+ data.tar.gz: 7b9f195720f60ab1803dd3d11fc54db948b6854e
5
5
  SHA512:
6
- metadata.gz: ddb3129bf814dff272dfd842b00e0d4017970fca04bbca5d096d72c458d18e5a24e0d1452a3df40b4e5b6c062591de45df1a1866a1599f6ce3cc56dba07883d9
7
- data.tar.gz: 1f6922686455ba1a9fed363d4d88be18cecaa883a8fe97a0f4fa1ba9dd482d52ccb888a4d27c2fce93cbce4ab50c23402ca9a00f1c6071ff9d671fc4fab6318f
6
+ metadata.gz: e4c96589f93b7bf9ce7b07c7bfbf3a459afc3e3e411be51242d5cba7eb21b263c1cedd072e45ce1b99ccd80d761d6a5f50011c41e1c471f5b2fef5368d9da397
7
+ data.tar.gz: 275a8aa593509842980f00d0cbb509f8b4180c885edef8eedf316938f73416ceb0673975c2feae9190f4fbf6c8e3c1a54155e971261fc71fd35f6f1b5b976a02
data/README.md CHANGED
@@ -44,6 +44,10 @@ do_expensive_computation()
44
44
  puts 'Done'
45
45
  ```
46
46
 
47
+ ## Known Issues
48
+
49
+ This module is not designed to work with ruby threads. If you set timers in multiple ruby threads at the same time some of them will not fire.
50
+
47
51
  ## Support
48
52
 
49
53
  Please report issues at https://github.com/nearbuy/ruby-itimer/issues
@@ -5,42 +5,53 @@ module Itimer
5
5
  end
6
6
 
7
7
  def self.timeout(seconds, klass=Timeout)
8
- @counter ||= 0
9
- @counter += 1
10
-
11
- catch_name = "itimer_#{@counter}"
12
-
13
- prev_handler = Signal.trap 'ALRM' do
14
- throw catch_name
15
- end
16
-
17
- prev = get(:real)
18
- start = Time.now
19
- if prev > 0
20
- seconds = [prev, seconds].min
21
- end
22
-
23
- timed_out = true
24
8
  ret = nil
25
9
 
26
- catch catch_name do
27
- set(:real, seconds)
28
- begin
29
- ret = yield
30
- timed_out = false
31
- ensure
32
- if prev > 0
33
- set(:real, [prev - (Time.now-start), 0.01].max)
34
- else
35
- set(:real, 0)
10
+ prev_timeout = @active_timeout
11
+ start = Time.now
12
+ absolute_timeout = start + seconds
13
+
14
+ if prev_timeout && absolute_timeout > prev_timeout
15
+ # this timer is nested in another one that will timeout before it,
16
+ # it will never fire
17
+ ret = yield
18
+ else
19
+ @counter ||= 0
20
+ @counter += 1
21
+
22
+ catch_name = "itimer_#{@counter}"
23
+
24
+ prev_handler = Signal.trap 'ALRM' do
25
+ begin
26
+ raise klass
27
+ rescue klass
28
+ throw(catch_name, $!)
36
29
  end
30
+ end
37
31
 
38
- Signal.trap('ALRM', prev_handler)
32
+ timed_out = true
33
+ @active_timeout = absolute_timeout
34
+
35
+ exception = catch(catch_name) do
36
+ set(:real, seconds)
37
+ begin
38
+ ret = yield
39
+ timed_out = false
40
+ ensure
41
+ @active_timeout = prev_timeout
42
+ if prev_timeout
43
+ set(:real, prev_timeout - Time.now)
44
+ else
45
+ set(:real, 0)
46
+ end
47
+
48
+ Signal.trap('ALRM', prev_handler)
49
+ end
39
50
  end
40
- end
41
51
 
42
- if timed_out
43
- raise klass
52
+ if timed_out
53
+ raise exception
54
+ end
44
55
  end
45
56
 
46
57
  return ret
@@ -140,22 +140,27 @@ class ItimerTest < Test::Unit::TestCase
140
140
  end
141
141
 
142
142
  def test_nested_timeouts_larger_inner
143
+ inner_exception = false
144
+ outer_exception = false
143
145
 
144
146
  start = Time.now
145
- timeouts = false
146
- assert_raise( Itimer::Timeout ) do
147
+ begin
147
148
  Itimer.timeout(0.25) do
148
149
  begin
149
150
  Itimer.timeout(3) do
150
151
  sleep 1
151
152
  end
152
153
  rescue Itimer::Timeout
153
- timeouts = true
154
+ inner_exception = true
154
155
  end
155
156
  sleep 1
156
157
  end
158
+ rescue Itimer::Timeout
159
+ outer_exception = true
157
160
  end
158
- assert( timeouts )
161
+
162
+ assert( outer_exception )
163
+ assert( !inner_exception )
159
164
  assert_in_delta( Time.now-start, 0.25, 0.1 )
160
165
  end
161
166
 
@@ -185,15 +190,17 @@ class ItimerTest < Test::Unit::TestCase
185
190
  begin
186
191
  sleep 0.5
187
192
  rescue Itimer::Timeout
188
- inner_exception = true
193
+ inner_exception = $!
189
194
  end
190
195
  end
191
196
  rescue Itimer::Timeout
192
- outer_exception = true
197
+ outer_exception = $!
193
198
  end
194
199
 
195
200
  assert( outer_exception )
196
201
  assert( !inner_exception )
202
+
203
+ assert( outer_exception.backtrace.find {|bt| bt.include?('sleep') } )
197
204
  end
198
205
 
199
206
  def test_throwing_exception_in_nested_itimer
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itimer
3
3
  version: !ruby/object:Gem::Version
4
- version: '8'
4
+ version: '9'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Mueller
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-11 00:00:00.000000000 Z
12
+ date: 2013-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler