itimer 8 → 9

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.
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