frugal_timeout 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/frugal_timeout.rb +48 -36
  2. metadata +2 -2
@@ -29,11 +29,11 @@ require 'timeout'
29
29
  #--
30
30
  # }}}1
31
31
  module FrugalTimeout
32
- # {{{2 Error
33
- class Error < Timeout::Error; end
32
+ # {{{1 Error
33
+ class Error < Timeout::Error; end # :nodoc:
34
34
 
35
- # {{{2 Request
36
- class Request
35
+ # {{{1 Request
36
+ class Request # :nodoc:
37
37
  include Comparable
38
38
  @@mutex = Mutex.new
39
39
 
@@ -60,10 +60,43 @@ module FrugalTimeout
60
60
  end
61
61
  end
62
62
 
63
- # {{{2 Main code
63
+ # {{{1 SleeperNotifier
64
+ class SleeperNotifier # :nodoc:
65
+ def initialize notifyQueue
66
+ @notifyQueue = notifyQueue
67
+ @delays, @mutex = Queue.new, Mutex.new
68
+
69
+ @thread = Thread.new {
70
+ loop {
71
+ sleepFor = nil
72
+ @mutex.synchronize {
73
+ sleepFor = @delays.shift until @delays.empty?
74
+ }
75
+ start = Time.now
76
+ sleepFor ? sleep(sleepFor) : sleep
77
+ @mutex.synchronize {
78
+ @notifyQueue.push :expired \
79
+ if sleepFor && Time.now - start >= sleepFor
80
+ }
81
+ }
82
+ }
83
+ ObjectSpace.define_finalizer self, proc { @thread.kill }
84
+ end
85
+
86
+ def notifyAfter sec
87
+ @mutex.synchronize {
88
+ sleep 0.01 until @thread.status == 'sleep'
89
+ @delays.push sec
90
+ @thread.wakeup
91
+ }
92
+ end
93
+ end
94
+
95
+ # {{{1 Main code
64
96
  @in = Queue.new
97
+ @sleeper = SleeperNotifier.new @in
65
98
 
66
- # {{{3 Timeout request and expiration processing thread
99
+ # {{{2 Timeout request and expiration processing thread
67
100
  Thread.new {
68
101
  nearestTimeout, requests = nil, []
69
102
  loop {
@@ -85,7 +118,7 @@ module FrugalTimeout
85
118
  nearestTimeout = unless requests.first
86
119
  nil
87
120
  else
88
- setupSleeper requests.first.at - now
121
+ @sleeper.notifyAfter requests.first.at - now
89
122
  requests.first.at
90
123
  end
91
124
 
@@ -104,28 +137,13 @@ module FrugalTimeout
104
137
  requests << request
105
138
  next if nearestTimeout && request.at > nearestTimeout
106
139
 
107
- setupSleeper request.at - now
140
+ @sleeper.notifyAfter request.at - now
108
141
  nearestTimeout = request.at
109
142
  }
110
143
  }
111
144
 
112
- # {{{3 Closest expiration notifier thread
113
- @sleeperDelays, @sleeperMutex = Queue.new, Mutex.new
114
- @sleeper = Thread.new {
115
- loop {
116
- sleepFor = nil
117
- @sleeperMutex.synchronize {
118
- sleepFor = @sleeperDelays.shift until @sleeperDelays.empty?
119
- }
120
- start = Time.now
121
- sleepFor ? sleep(sleepFor) : sleep
122
- @sleeperMutex.synchronize {
123
- @in.push :expired if sleepFor && Time.now - start >= sleepFor
124
- }
125
- }
126
- }
127
145
 
128
- # {{{3 Methods
146
+ # {{{2 Methods
129
147
 
130
148
  # Ensure that calling timeout() will use FrugalTimeout.timeout()
131
149
  def self.dropin!
@@ -135,22 +153,16 @@ module FrugalTimeout
135
153
  end'
136
154
  end
137
155
 
138
- def self.setupSleeper sleepFor # :nodoc:
139
- @sleeperMutex.synchronize {
140
- sleep 0.1 until @sleeper.status == 'sleep'
141
- @sleeperDelays.push sleepFor
142
- @sleeper.wakeup
143
- }
144
- end
145
-
146
156
  # Same as Timeout.timeout()
147
- def self.timeout t, klass=nil
148
- @in.push request = Request.new(Thread.current, Time.now + t, klass)
157
+ def self.timeout sec, klass=nil
158
+ return yield sec if sec == nil || sec <= 0
159
+
160
+ @in.push request = Request.new(Thread.current, Time.now + sec, klass)
149
161
  begin
150
- yield t
162
+ yield sec
151
163
  ensure
152
164
  request.done! unless $!.is_a? FrugalTimeout::Error
153
165
  end
154
166
  end
155
- # }}}2
167
+ # }}}1
156
168
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: frugal_timeout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-19 00:00:00.000000000 Z
12
+ date: 2013-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec