servolux 0.5.0 → 0.6.0
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.
- data/History.txt +7 -1
- data/lib/servolux/threaded.rb +85 -7
- data/lib/servolux.rb +1 -1
- data/spec/threaded_spec.rb +43 -0
- metadata +2 -2
data/History.txt
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
+
== 0.6.0 / 2009-07-07
|
2
|
+
|
3
|
+
* 2 Minor Enhancements
|
4
|
+
* Threaded objects can be set to run only a given number of times
|
5
|
+
* Threaded objects can now continue on error
|
6
|
+
|
1
7
|
== 0.5.0 / 2009-06-30
|
2
8
|
|
3
|
-
* 2 Minor
|
9
|
+
* 2 Minor Enhancements
|
4
10
|
* Added tests for the Child class
|
5
11
|
* Updating documentation in preperation for a release
|
6
12
|
|
data/lib/servolux/threaded.rb
CHANGED
@@ -57,17 +57,28 @@ module Servolux::Threaded
|
|
57
57
|
|
58
58
|
before_starting if self.respond_to?(:before_starting)
|
59
59
|
@activity_thread_running = true
|
60
|
+
@activity_thread_iterations = 0
|
60
61
|
@activity_thread = Thread.new {
|
61
62
|
begin
|
62
63
|
loop {
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
begin
|
65
|
+
sleep interval if running?
|
66
|
+
break unless running?
|
67
|
+
run
|
68
|
+
@activity_thread_iterations += 1
|
69
|
+
break if finished_iterations?
|
70
|
+
rescue SystemExit; raise
|
71
|
+
rescue Exception => err
|
72
|
+
if continue_on_error?
|
73
|
+
logger.error err
|
74
|
+
else
|
75
|
+
logger.fatal err
|
76
|
+
raise err
|
77
|
+
end
|
78
|
+
end
|
66
79
|
}
|
67
|
-
|
80
|
+
ensure
|
68
81
|
@activity_thread_running = false
|
69
|
-
logger.fatal err unless err.is_a?(SystemExit)
|
70
|
-
raise err
|
71
82
|
end
|
72
83
|
}
|
73
84
|
after_starting if self.respond_to?(:after_starting)
|
@@ -96,6 +107,20 @@ module Servolux::Threaded
|
|
96
107
|
self
|
97
108
|
end
|
98
109
|
|
110
|
+
# Wait on the activity thread. If the thread is already stopped, this
|
111
|
+
# method will return without taking any action. Otherwise, this method
|
112
|
+
# does not return until the activity thread has stopped, or a specific
|
113
|
+
# number of iterations has passed since this method was called.
|
114
|
+
#
|
115
|
+
def wait( limit = nil )
|
116
|
+
return self unless running?
|
117
|
+
start_waiting_iterations = self.iterations
|
118
|
+
loop {
|
119
|
+
break unless running?
|
120
|
+
break if limit and self.iterations > ( start_waiting_iterations + limit )
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
99
124
|
# If the activity thread is running, the calling thread will suspend
|
100
125
|
# execution and run the activity thread. This method does not return until
|
101
126
|
# the activity thread is stopped or until _limit_ seconds have passed.
|
@@ -115,6 +140,16 @@ module Servolux::Threaded
|
|
115
140
|
@activity_thread_running
|
116
141
|
end
|
117
142
|
|
143
|
+
# Returns +true+ if the activity thread has finished its maximum
|
144
|
+
# number of iterations or the thread is no longer running.
|
145
|
+
# Returns +false+ otherwise.
|
146
|
+
#
|
147
|
+
def finished_iterations?
|
148
|
+
return true unless running?
|
149
|
+
return true if maximum_iterations and (iterations >= maximum_iterations)
|
150
|
+
return false
|
151
|
+
end
|
152
|
+
|
118
153
|
# Returns the status of threaded object.
|
119
154
|
#
|
120
155
|
# 'sleep' : sleeping or waiting on I/O
|
@@ -142,7 +177,50 @@ module Servolux::Threaded
|
|
142
177
|
# threaded object's 'run' method.
|
143
178
|
#
|
144
179
|
def interval
|
145
|
-
@activity_thread_interval
|
180
|
+
@activity_thread_interval ||= 60
|
181
|
+
end
|
182
|
+
|
183
|
+
# Sets the maximum number of invocations of the threaded object's
|
184
|
+
# 'run' method
|
185
|
+
#
|
186
|
+
def maximum_iterations=( value )
|
187
|
+
raise ArgumentError, "maximum iterations must be >= 1" unless value.to_i >= 1
|
188
|
+
@activity_thread_maximum_iterations = value.to_i
|
189
|
+
end
|
190
|
+
|
191
|
+
# Returns the maximum number of invocations of the threaded
|
192
|
+
# object's 'run' method
|
193
|
+
#
|
194
|
+
def maximum_iterations
|
195
|
+
return unless defined? @activity_thread_maximum_iterations
|
196
|
+
@activity_thread_maximum_iterations
|
197
|
+
end
|
198
|
+
|
199
|
+
# Returns the number of iterations of the threaded object's 'run' method
|
200
|
+
# completed thus far.
|
201
|
+
#
|
202
|
+
def iterations
|
203
|
+
@activity_thread_iterations ||= 0
|
204
|
+
end
|
205
|
+
|
206
|
+
# Set to +true+ to continue running the threaded object even if an error
|
207
|
+
# is raised by the +run+ method. The default behavior is to stop the
|
208
|
+
# activity thread when an error is raised by the run method.
|
209
|
+
#
|
210
|
+
# A SystemExit will never be caught; it will always cause the Ruby
|
211
|
+
# interpreter to exit.
|
212
|
+
#
|
213
|
+
def continue_on_error=( value )
|
214
|
+
@activity_thread_continue_on_error = (value ? true : false)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Returns +true+ if the threded object should continue running even if an
|
218
|
+
# error is raised by the run method. The default is to return +false+. The
|
219
|
+
# threaded object will stop running when an error is raised.
|
220
|
+
#
|
221
|
+
def continue_on_error?
|
222
|
+
return @activity_thread_continue_on_error if defined? @activity_thread_continue_on_error
|
223
|
+
@activity_thread_continue_on_error = false
|
146
224
|
end
|
147
225
|
|
148
226
|
# :stopdoc:
|
data/lib/servolux.rb
CHANGED
data/spec/threaded_spec.rb
CHANGED
@@ -90,6 +90,32 @@ describe Servolux::Threaded do
|
|
90
90
|
lambda { obj.join }.should raise_error(RuntimeError, 'ni')
|
91
91
|
end
|
92
92
|
|
93
|
+
it "lives if told to continue on error" do
|
94
|
+
klass = Class.new(base) do
|
95
|
+
def run()
|
96
|
+
@sleep ||= false
|
97
|
+
if @sleep then sleep
|
98
|
+
else
|
99
|
+
@sleep = true
|
100
|
+
raise 'ni'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
obj = klass.new
|
106
|
+
obj.continue_on_error = true
|
107
|
+
|
108
|
+
obj.start
|
109
|
+
obj.pass
|
110
|
+
|
111
|
+
obj.running?.should be_true
|
112
|
+
@log_output.readline
|
113
|
+
@log_output.readline.chomp.should == "ERROR Object : <RuntimeError> ni"
|
114
|
+
|
115
|
+
obj.stop(2)
|
116
|
+
obj.running?.should be_false
|
117
|
+
end
|
118
|
+
|
93
119
|
it "complains loudly if you don't have a run method" do
|
94
120
|
obj = base.new
|
95
121
|
obj.start
|
@@ -100,6 +126,23 @@ describe Servolux::Threaded do
|
|
100
126
|
|
101
127
|
lambda { obj.join }.should raise_error(NotImplementedError, 'The run method must be defined by the threaded object.')
|
102
128
|
end
|
129
|
+
|
130
|
+
it "stops after a limited number of iterations" do
|
131
|
+
klass = Class.new( base ) do
|
132
|
+
def run() ; end
|
133
|
+
end
|
134
|
+
obj = klass.new
|
135
|
+
obj.maximum_iterations = 5
|
136
|
+
obj.iterations.should == 0
|
137
|
+
obj.start
|
138
|
+
obj.wait
|
139
|
+
obj.iterations.should == 5
|
140
|
+
end
|
141
|
+
|
142
|
+
it "complains loudly if you attempt to set a maximum number of iterations < 1" do
|
143
|
+
obj = base.new
|
144
|
+
lambda { obj.maximum_iterations = -1 }.should raise_error( ArgumentError, "maximum iterations must be >= 1" )
|
145
|
+
end
|
103
146
|
end
|
104
147
|
|
105
148
|
# EOF
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: servolux
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Pease
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-07 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|