frugal_timeout 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/frugal_timeout.rb +42 -14
- metadata +19 -2
data/lib/frugal_timeout.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Copyright (C) 2013 by Dmitry Maksyoma <ledestin@gmail.com>
|
2
2
|
|
3
|
+
require 'hitimes'
|
3
4
|
require 'thread'
|
4
5
|
require 'timeout'
|
5
6
|
|
@@ -32,6 +33,20 @@ module FrugalTimeout
|
|
32
33
|
# {{{1 Error
|
33
34
|
class Error < Timeout::Error; end # :nodoc:
|
34
35
|
|
36
|
+
# {{{1 MonotonicTime
|
37
|
+
class MonotonicTime
|
38
|
+
NANOS_IN_SECOND = 1_000_000_000
|
39
|
+
|
40
|
+
def self.measure
|
41
|
+
start = now
|
42
|
+
yield
|
43
|
+
now - start
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.now
|
47
|
+
Hitimes::Interval.now.start_instant.to_f/NANOS_IN_SECOND
|
48
|
+
end
|
49
|
+
end
|
35
50
|
# {{{1 Request
|
36
51
|
class Request # :nodoc:
|
37
52
|
include Comparable
|
@@ -64,32 +79,44 @@ module FrugalTimeout
|
|
64
79
|
class SleeperNotifier # :nodoc:
|
65
80
|
def initialize notifyQueue
|
66
81
|
@notifyQueue = notifyQueue
|
67
|
-
@
|
82
|
+
@latestDelay, @mutex = nil, Mutex.new
|
68
83
|
|
69
84
|
@thread = Thread.new {
|
70
85
|
loop {
|
71
|
-
sleepFor =
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@notifyQueue.push :expired \
|
79
|
-
if sleepFor && Time.now - start >= sleepFor
|
86
|
+
unless sleepFor = latestDelay
|
87
|
+
sleep
|
88
|
+
else
|
89
|
+
sleptFor = MonotonicTime.measure { sleep(sleepFor) }
|
90
|
+
end
|
91
|
+
synchronize {
|
92
|
+
@notifyQueue.push :expired if sleepFor && sleptFor >= sleepFor
|
80
93
|
}
|
81
94
|
}
|
82
95
|
}
|
83
96
|
ObjectSpace.define_finalizer self, proc { @thread.kill }
|
84
97
|
end
|
85
98
|
|
99
|
+
def latestDelay
|
100
|
+
synchronize {
|
101
|
+
tmp = @latestDelay
|
102
|
+
@latestDelay = nil
|
103
|
+
tmp
|
104
|
+
}
|
105
|
+
end
|
106
|
+
private :latestDelay
|
107
|
+
|
86
108
|
def notifyAfter sec
|
87
|
-
|
109
|
+
synchronize {
|
88
110
|
sleep 0.01 until @thread.status == 'sleep'
|
89
|
-
@
|
111
|
+
@latestDelay = sec
|
90
112
|
@thread.wakeup
|
91
113
|
}
|
92
114
|
end
|
115
|
+
|
116
|
+
def synchronize &b
|
117
|
+
@mutex.synchronize &b
|
118
|
+
end
|
119
|
+
private :synchronize
|
93
120
|
end
|
94
121
|
|
95
122
|
# {{{1 Main code
|
@@ -101,7 +128,7 @@ module FrugalTimeout
|
|
101
128
|
nearestTimeout, requests = nil, []
|
102
129
|
loop {
|
103
130
|
request = @in.shift
|
104
|
-
now =
|
131
|
+
now = MonotonicTime.now
|
105
132
|
|
106
133
|
if request == :expired
|
107
134
|
# Enforce all expired timeouts.
|
@@ -157,7 +184,8 @@ module FrugalTimeout
|
|
157
184
|
def self.timeout sec, klass=nil
|
158
185
|
return yield sec if sec == nil || sec <= 0
|
159
186
|
|
160
|
-
@in.push request = Request.new(Thread.current,
|
187
|
+
@in.push request = Request.new(Thread.current, MonotonicTime.now + sec,
|
188
|
+
klass)
|
161
189
|
begin
|
162
190
|
yield sec
|
163
191
|
ensure
|
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.
|
4
|
+
version: 0.0.7
|
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-
|
12
|
+
date: 2013-10-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '2.13'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: hitimes
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.2'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.2'
|
30
46
|
description: Timeout.timeout replacement that uses only 2 threads
|
31
47
|
email: ledestin@gmail.com
|
32
48
|
executables: []
|
@@ -59,3 +75,4 @@ signing_key:
|
|
59
75
|
specification_version: 3
|
60
76
|
summary: Timeout.timeout replacement
|
61
77
|
test_files: []
|
78
|
+
has_rdoc:
|