frugal_timeout 0.0.5 → 0.0.6

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