thread 0.0.7 → 0.0.8
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.
- checksums.yaml +4 -4
- data/README.md +24 -0
- data/Rakefile +1 -0
- data/lib/thread/every.rb +197 -0
- data/lib/thread/future.rb +12 -1
- data/lib/thread/pipe.rb +2 -2
- data/lib/thread/promise.rb +1 -1
- data/tests/every_spec.rb +11 -0
- data/thread.gemspec +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8caeb122b45ef1fbfce75eae1c2f313ff356060
|
4
|
+
data.tar.gz: 5e851cb4ac1a270cf461fe4e4658168aac1bdb0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e54a7cab6bfbb3144a2aa506804d5f9a4ea7b38c42f2e9ff2a55ace0dc0fce6a8554fa0de251041fa8fad8e481f70daf037076a9f9ef15d09fcd3394dd124739
|
7
|
+
data.tar.gz: 64b5e21bff244a09cd7fa5696d87533a7cfe0bd5622de3143c6b53a4d9c396abd43c0e0a5fdea8172dc64419419a4bf8b7fde93a11f7e7f7ee2be9aec6ddbcfe
|
data/README.md
CHANGED
@@ -169,3 +169,27 @@ d = Thread.delay {
|
|
169
169
|
|
170
170
|
puts ~d # => 42
|
171
171
|
```
|
172
|
+
|
173
|
+
Every
|
174
|
+
=====
|
175
|
+
An every executes the block every given seconds and yields the value to the
|
176
|
+
every object, you can then check if the current value is old or how much time
|
177
|
+
is left until the second call is done.
|
178
|
+
|
179
|
+
Example
|
180
|
+
-------
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
require 'net/http'
|
184
|
+
require 'thread/every'
|
185
|
+
|
186
|
+
e = Thread.every(5) {
|
187
|
+
Net::HTTP.get(URI.parse('http://www.whattimeisit.com/')).match %r{<B>(.*?)<BR>\s+(.*?)</B>}m do |m|
|
188
|
+
{ date: m[1], time: m[2] }
|
189
|
+
end
|
190
|
+
}
|
191
|
+
|
192
|
+
loop do
|
193
|
+
puts ~e
|
194
|
+
end
|
195
|
+
```
|
data/Rakefile
CHANGED
@@ -16,5 +16,6 @@ task :test do
|
|
16
16
|
sh 'rspec future_spec.rb --backtrace --color --format doc'
|
17
17
|
sh 'rspec delay_spec.rb --backtrace --color --format doc'
|
18
18
|
sh 'rspec pipe_spec.rb --backtrace --color --format doc'
|
19
|
+
sh 'rspec every_spec.rb --backtrace --color --format doc'
|
19
20
|
end
|
20
21
|
end
|
data/lib/thread/every.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
require 'thread'
|
12
|
+
|
13
|
+
# An every runs the given block every given seconds, you can then get the
|
14
|
+
# value, check if the value is old and you can check how many seconds
|
15
|
+
# until the next run.
|
16
|
+
class Thread::Every
|
17
|
+
Cancel = Class.new(Exception)
|
18
|
+
Restart = Class.new(Exception)
|
19
|
+
|
20
|
+
# Create an every with the given seconds and block.
|
21
|
+
def initialize (every, &block)
|
22
|
+
raise ArgumentError, 'no block given' unless block
|
23
|
+
|
24
|
+
@every = every
|
25
|
+
@old = true
|
26
|
+
@mutex = Mutex.new
|
27
|
+
@thread = Thread.new {
|
28
|
+
loop do
|
29
|
+
begin
|
30
|
+
value = block.call
|
31
|
+
|
32
|
+
@mutex.synchronize {
|
33
|
+
@at = Time.now
|
34
|
+
@value = value
|
35
|
+
@old = false
|
36
|
+
@exception = nil
|
37
|
+
}
|
38
|
+
rescue Restart
|
39
|
+
next
|
40
|
+
rescue Exception => e
|
41
|
+
@mutex.synchronize {
|
42
|
+
@at = Time.now
|
43
|
+
@exception = e
|
44
|
+
}
|
45
|
+
|
46
|
+
break if e.is_a? Cancel
|
47
|
+
end
|
48
|
+
|
49
|
+
cond.broadcast if cond?
|
50
|
+
|
51
|
+
begin
|
52
|
+
sleep @every
|
53
|
+
rescue Restart
|
54
|
+
next
|
55
|
+
rescue Cancel => e
|
56
|
+
@mutex.synchronize {
|
57
|
+
@at = Time.now
|
58
|
+
@exception = e
|
59
|
+
}
|
60
|
+
|
61
|
+
break
|
62
|
+
end
|
63
|
+
end
|
64
|
+
}
|
65
|
+
|
66
|
+
ObjectSpace.define_finalizer self, self.class.finalizer(@thread)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @private
|
70
|
+
def self.finalizer (thread)
|
71
|
+
proc {
|
72
|
+
thread.raise Cancel.new
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Change the number of seconds between each call.
|
77
|
+
def every (seconds)
|
78
|
+
@every = seconds
|
79
|
+
|
80
|
+
restart
|
81
|
+
end
|
82
|
+
|
83
|
+
# Cancel the every, {#value} will yield a Cancel exception.
|
84
|
+
def cancel
|
85
|
+
@mutex.synchronize {
|
86
|
+
@thread.raise Cancel.new('every cancelled')
|
87
|
+
}
|
88
|
+
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
92
|
+
# Check if the every has been cancelled.
|
93
|
+
def cancelled?
|
94
|
+
@mutex.synchronize {
|
95
|
+
@exception.is_a? Cancel
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
# Checks when the every was cancelled.
|
100
|
+
def cancelled_at
|
101
|
+
if cancelled?
|
102
|
+
@mutex.synchronize {
|
103
|
+
@at
|
104
|
+
}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Restart the every.
|
109
|
+
def restart
|
110
|
+
@mutex.synchronize {
|
111
|
+
@thread.raise Restart.new
|
112
|
+
}
|
113
|
+
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
117
|
+
# Check if the every is running.
|
118
|
+
def running?
|
119
|
+
!cancelled?
|
120
|
+
end
|
121
|
+
|
122
|
+
# Check if the every is old, after the first #value call it becomes old,
|
123
|
+
# until another run of the block is gone)
|
124
|
+
def old?
|
125
|
+
@mutex.synchronize {
|
126
|
+
@old
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
# Gets the Time when the block was called.
|
131
|
+
def called_at
|
132
|
+
@mutex.synchronize {
|
133
|
+
@at
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
# Gets how many seconds are missing before another call.
|
138
|
+
def next_in
|
139
|
+
return if cancelled?
|
140
|
+
|
141
|
+
@mutex.synchronize {
|
142
|
+
@every - (Time.now - @at)
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
# Gets the current every value.
|
147
|
+
def value (timeout = nil)
|
148
|
+
@mutex.synchronize {
|
149
|
+
if @old
|
150
|
+
cond.wait(@mutex, *timeout)
|
151
|
+
end
|
152
|
+
|
153
|
+
@old = true
|
154
|
+
|
155
|
+
if @exception
|
156
|
+
raise @exception
|
157
|
+
else
|
158
|
+
@value
|
159
|
+
end
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
alias ~ value
|
164
|
+
|
165
|
+
# Gets the current every value, without blocking and waiting for the next
|
166
|
+
# call.
|
167
|
+
def value!
|
168
|
+
@mutex.synchronize {
|
169
|
+
@old = true
|
170
|
+
|
171
|
+
@value unless @exception
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
def cond?
|
177
|
+
instance_variable_defined? :@cond
|
178
|
+
end
|
179
|
+
|
180
|
+
def cond
|
181
|
+
@cond ||= ConditionVariable.new
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
class Thread
|
186
|
+
# Helper to create an every
|
187
|
+
def self.every (every, &block)
|
188
|
+
Thread::Every.new(every, &block)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
module Kernel
|
193
|
+
# Helper to create an every
|
194
|
+
def every (every, &block)
|
195
|
+
Thread::Every.new(every, &block)
|
196
|
+
end
|
197
|
+
end
|
data/lib/thread/future.rb
CHANGED
@@ -33,6 +33,15 @@ class Thread::Future
|
|
33
33
|
}
|
34
34
|
|
35
35
|
@thread = pool ? pool.process(&task) : Thread.new(&task)
|
36
|
+
|
37
|
+
ObjectSpace.define_finalizer self, self.class.finalizer(@thread)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @private
|
41
|
+
def self.finalizer (thread)
|
42
|
+
proc {
|
43
|
+
thread.raise Cancel.new
|
44
|
+
}
|
36
45
|
end
|
37
46
|
|
38
47
|
# Check if an exception has been raised.
|
@@ -60,11 +69,13 @@ class Thread::Future
|
|
60
69
|
|
61
70
|
# Cancel the future, {#value} will yield a Cancel exception
|
62
71
|
def cancel
|
63
|
-
return if delivered?
|
72
|
+
return self if delivered?
|
64
73
|
|
65
74
|
@mutex.synchronize {
|
66
75
|
@thread.raise Cancel.new('future cancelled')
|
67
76
|
}
|
77
|
+
|
78
|
+
self
|
68
79
|
end
|
69
80
|
|
70
81
|
# Check if the future has been cancelled
|
data/lib/thread/pipe.rb
CHANGED
@@ -60,11 +60,11 @@ class Thread::Pipe
|
|
60
60
|
@input = input
|
61
61
|
@output = output
|
62
62
|
|
63
|
-
ObjectSpace.define_finalizer
|
63
|
+
ObjectSpace.define_finalizer self, self.class.finalizer(@tasks)
|
64
64
|
end
|
65
65
|
|
66
66
|
# @private
|
67
|
-
def self.
|
67
|
+
def self.finalizer (tasks)
|
68
68
|
proc {
|
69
69
|
tasks.each(&:kill)
|
70
70
|
}
|
data/lib/thread/promise.rb
CHANGED
data/tests/every_spec.rb
ADDED
data/thread.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thread
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- meh.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- Rakefile
|
51
51
|
- lib/thread/channel.rb
|
52
52
|
- lib/thread/delay.rb
|
53
|
+
- lib/thread/every.rb
|
53
54
|
- lib/thread/future.rb
|
54
55
|
- lib/thread/pipe.rb
|
55
56
|
- lib/thread/pool.rb
|
@@ -58,6 +59,7 @@ files:
|
|
58
59
|
- lib/thread/recursive_mutex.rb
|
59
60
|
- tests/channel_spec.rb
|
60
61
|
- tests/delay_spec.rb
|
62
|
+
- tests/every_spec.rb
|
61
63
|
- tests/future_spec.rb
|
62
64
|
- tests/pipe_spec.rb
|
63
65
|
- tests/promise_spec.rb
|