rjr 0.12.2 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/README.md +49 -36
  2. data/Rakefile +2 -0
  3. data/bin/rjr-client +11 -9
  4. data/bin/rjr-server +12 -10
  5. data/examples/amqp.rb +29 -0
  6. data/examples/client.rb +32 -0
  7. data/examples/complete.rb +36 -0
  8. data/examples/local.rb +29 -0
  9. data/examples/server.rb +26 -0
  10. data/examples/tcp.rb +29 -0
  11. data/examples/web.rb +22 -0
  12. data/examples/ws.rb +29 -0
  13. data/lib/rjr/common.rb +7 -12
  14. data/lib/rjr/dispatcher.rb +171 -239
  15. data/lib/rjr/em_adapter.rb +33 -66
  16. data/lib/rjr/message.rb +43 -12
  17. data/lib/rjr/node.rb +197 -103
  18. data/lib/rjr/nodes/amqp.rb +216 -0
  19. data/lib/rjr/nodes/easy.rb +159 -0
  20. data/lib/rjr/nodes/local.rb +118 -0
  21. data/lib/rjr/{missing_node.rb → nodes/missing.rb} +4 -2
  22. data/lib/rjr/nodes/multi.rb +79 -0
  23. data/lib/rjr/nodes/tcp.rb +211 -0
  24. data/lib/rjr/nodes/web.rb +197 -0
  25. data/lib/rjr/nodes/ws.rb +187 -0
  26. data/lib/rjr/stats.rb +70 -0
  27. data/lib/rjr/thread_pool.rb +178 -123
  28. data/site/index.html +45 -0
  29. data/site/jquery-latest.js +9404 -0
  30. data/site/jrw.js +297 -0
  31. data/site/json.js +199 -0
  32. data/specs/dispatcher_spec.rb +244 -198
  33. data/specs/em_adapter_spec.rb +52 -80
  34. data/specs/message_spec.rb +223 -197
  35. data/specs/node_spec.rb +67 -163
  36. data/specs/nodes/amqp_spec.rb +82 -0
  37. data/specs/nodes/easy_spec.rb +13 -0
  38. data/specs/nodes/local_spec.rb +72 -0
  39. data/specs/nodes/multi_spec.rb +65 -0
  40. data/specs/nodes/tcp_spec.rb +75 -0
  41. data/specs/nodes/web_spec.rb +77 -0
  42. data/specs/nodes/ws_spec.rb +78 -0
  43. data/specs/stats_spec.rb +59 -0
  44. data/specs/thread_pool_spec.rb +44 -35
  45. metadata +40 -30
  46. data/lib/rjr/amqp_node.rb +0 -330
  47. data/lib/rjr/inspect.rb +0 -65
  48. data/lib/rjr/local_node.rb +0 -150
  49. data/lib/rjr/multi_node.rb +0 -65
  50. data/lib/rjr/tcp_node.rb +0 -323
  51. data/lib/rjr/thread_pool2.rb +0 -272
  52. data/lib/rjr/util.rb +0 -104
  53. data/lib/rjr/web_node.rb +0 -266
  54. data/lib/rjr/ws_node.rb +0 -289
  55. data/lib/rjr.rb +0 -16
  56. data/specs/amqp_node_spec.rb +0 -31
  57. data/specs/inspect_spec.rb +0 -60
  58. data/specs/local_node_spec.rb +0 -43
  59. data/specs/multi_node_spec.rb +0 -45
  60. data/specs/tcp_node_spec.rb +0 -33
  61. data/specs/util_spec.rb +0 -46
  62. data/specs/web_node_spec.rb +0 -32
  63. data/specs/ws_node_spec.rb +0 -32
  64. /data/lib/rjr/{tcp_node2.rb → nodes/tcp2.rb} +0 -0
  65. /data/lib/rjr/{udp_node.rb → nodes/udp.rb} +0 -0
@@ -1,225 +1,271 @@
1
1
  require 'rjr/dispatcher'
2
2
 
3
- describe RJR::Request do
4
- it "invokes registered handler in request context" do
5
- invoked = false
6
- rjr_callback = Object.new
7
- request = RJR::Request.new :method => 'foobar',
8
- :method_args => ['a', 123],
9
- :headers => {'qqq' => 'www'},
10
- :rjr_callback => rjr_callback,
11
- :rjr_node_id => 'test',
12
- :rjr_node_type => 'test_type',
13
- :handler => lambda { |p1, p2|
14
- invoked = true
15
- @method.should == 'foobar'
16
- p1.should == 'a'
17
- p2.should == 123
18
- @headers['qqq'].should == 'www'
19
- @rjr_callback.should == rjr_callback
20
- @rjr_node_id.should == 'test'
21
- @rjr_node_type.should == 'test_type'
22
- }
23
- request.handle
24
- invoked.should == true
25
- end
26
- end
3
+ module RJR
4
+ describe Result do
5
+ describe "#initialize" do
6
+ it "initializes default attributes" do
7
+ result = Result.new
8
+ result.result.should be_nil
9
+ result.error_code.should be_nil
10
+ result.error_msg.should be_nil
11
+ result.error_class.should be_nil
12
+ end
27
13
 
28
- describe RJR::Result do
29
- it "should handle successful results" do
30
- result = RJR::Result.new :result => 'foobar'
31
- result.success.should == true
32
- result.failed.should == false
33
- result.result.should == 'foobar'
34
- result.error_code.should == nil
35
- result.error_msg.should == nil
36
- result.error_class.should == nil
37
- end
14
+ it "stores result" do
15
+ result = Result.new :result => 'foobar'
16
+ result.result.should == 'foobar'
17
+ end
38
18
 
39
- it "should handle errors" do
40
- result = RJR::Result.new :error_code => 123, :error_msg => 'abc', :error_class => ArgumentError
41
- result.success.should == false
42
- result.failed.should == true
43
- result.result.should == nil
44
- result.error_code.should == 123
45
- result.error_msg.should == 'abc'
46
- result.error_class.should == ArgumentError
47
- end
48
- end
19
+ it "stores error" do
20
+ result = Result.new :error_code => 123, :error_msg => 'abc',
21
+ :error_class => ArgumentError
22
+ result.error_code.should == 123
23
+ result.error_msg.should == 'abc'
24
+ result.error_class.should == ArgumentError
25
+ end
49
26
 
27
+ context "when an error code is not specified" do
28
+ it "should be marked as successful" do
29
+ result = Result.new
30
+ result.success.should == true
31
+ result.failed.should == false
32
+ end
33
+ end
50
34
 
51
- describe RJR::Handler do
52
- before(:each) do
53
- RJR::DispatcherStat.reset
54
- end
35
+ context "when an error code is specified" do
36
+ it "should be marked as failed" do
37
+ result = Result.new :error_code => 123
38
+ result.success.should == false
39
+ result.failed.should == true
40
+ end
41
+ end
55
42
 
56
- it "should return method not found result if method name is not specified" do
57
- handler = RJR::Handler.new :method => nil
58
- result = handler.handle
59
- result.should == RJR::Result.method_not_found(nil)
60
- end
43
+ end # describe #initialize
61
44
 
62
- it "should invoke registered handler for request" do
63
- invoked = false
64
- handler = RJR::Handler.new :method => 'foobar',
65
- :handler => lambda {
66
- invoked = true
67
- }
68
- handler.handle({:method_args => [] })
69
- invoked.should == true
70
- end
45
+ describe "#==" do
46
+ it "return true for equal results"
47
+ it "return false for inequal results"
48
+ end # descirbe #==
71
49
 
72
- it "should create dispatcher stat when invoking handler" do
73
- handler = RJR::Handler.new :method => 'foobar',
74
- :handler => lambda { 42 }
75
- handler.handle({:method_args => [] })
76
- RJR::DispatcherStat.stats.size.should == 1
77
- RJR::DispatcherStat.stats.first.request.method.should == 'foobar'
78
- RJR::DispatcherStat.stats.first.result.result.should == 42
79
- end
50
+ end # describe Result
51
+ end # module RJR
80
52
 
81
- it "should return handler's return value in successful result" do
82
- retval = Object.new
83
- handler = RJR::Handler.new :method => 'foobar',
84
- :handler => lambda {
85
- retval
86
- }
87
- res = handler.handle({:method_args => [] })
88
- res.success.should == true
89
- res.result.should == retval
90
- end
53
+ module RJR
54
+ describe Request do
55
+ it "should be convertable to json" do
56
+ req = Request.new :rjr_method => 'foobar',
57
+ :rjr_method_args => [:a, :b],
58
+ :rjr_headers => { :header1 => :val1 },
59
+ :rjr_node_type => :local,
60
+ :rjr_node_id => :loc1
91
61
 
92
- it "should catch handler errors and return error result" do
93
- handler = RJR::Handler.new :method => 'foobar',
94
- :method_args => [],
95
- :handler => lambda {
96
- raise ArgumentError, "uh oh!"
97
- }
98
- res = handler.handle({:method_args => [] })
99
- res.failed.should == true
100
- res.error_code.should == -32000
101
- res.error_msg.should == "uh oh!"
102
- res.error_class.should == ArgumentError
103
- end
104
- end
62
+ res = RJR::Result.new :result => 42,
63
+ :error_code => 123,
64
+ :error_msg => 'error occurred',
65
+ :error_class => 'ArgumentError'
66
+ req.result = res
105
67
 
106
- describe RJR::DispatcherStat do
107
- before(:each) do
108
- RJR::DispatcherStat.reset
109
- end
68
+ j = req.to_json()
69
+ j.should include('"json_class":"RJR::Request"')
70
+ j.should include('"rjr_method":"foobar"')
71
+ j.should include('"rjr_method_args":["a","b"]')
72
+ j.should include('"rjr_headers":{"header1":"val1"}')
73
+ j.should include('"rjr_node_type":"local"')
74
+ j.should include('"rjr_node_id":"loc1"')
75
+ j.should include('"result":42')
76
+ j.should include('"error_code":123')
77
+ j.should include('"error_msg":"error occurred"')
78
+ j.should include('"error_class":"ArgumentError"')
79
+ end
110
80
 
111
- it "should store request and result" do
112
- req = RJR::Request.new
113
- res = RJR::Result.new
114
- stat = RJR::DispatcherStat.new req, res
115
- (stat.request == req).should be_true
116
- stat.result.should == res
117
- end
81
+ it "should be convertable from json" do
82
+ j = '{"json_class":"RJR::Request","data":{"request":{"rjr_method":"foobar","rjr_method_args":["a","b"],"rjr_headers":{"foo":"bar"},"rjr_node_type":"local","rjr_node_id":"loc1"},"result":{"result":42,"error_code":null,"error_msg":null,"error_class":null}}}'
83
+ r = JSON.parse(j)
118
84
 
119
- it "should track global stats" do
120
- req = RJR::Request.new
121
- res = RJR::Result.new
122
- stat = RJR::DispatcherStat.new req, res
85
+ r.class.should == RJR::Request
86
+ r.rjr_method.should == 'foobar'
87
+ r.rjr_method_args.should == ['a', 'b']
88
+ r.rjr_headers.should == { 'foo' => 'bar' }
89
+ r.rjr_node_type.should == 'local'
90
+ r.rjr_node_id.should == 'loc1'
91
+ r.result.result.should == 42
92
+ end
123
93
 
124
- RJR::DispatcherStat << stat
125
- RJR::DispatcherStat.stats.should include(stat)
126
- end
94
+ context "handling" do
95
+ it "should invoke handler in request context" do
96
+ method = 'foobar'
97
+ params = ['a', 1]
98
+ ni = 'test'
99
+ nt = 'test_type'
100
+ cb = Object.new
101
+ headers = {'header1' => 'val1'}
127
102
 
128
- it "should be convertable to json" do
129
- req = RJR::Request.new :method => 'foobar', :method_args => [:a, :b],
130
- :headers => { :foo => :bar }, :rjr_node_type => :local,
131
- :rjr_node_id => :loc1
132
- res = RJR::Result.new :result => 42
133
-
134
- stat = RJR::DispatcherStat.new req, res
135
- j = stat.to_json()
136
- j.should include('"json_class":"RJR::DispatcherStat"')
137
- j.should include('"method":"foobar"')
138
- j.should include('"method_args":["a","b"]')
139
- j.should include('"headers":{"foo":"bar"}')
140
- j.should include('"rjr_node_type":"local"')
141
- j.should include('"rjr_node_id":"loc1"')
142
- j.should include('"result":42')
143
- end
103
+ invoked = ip1 = ip2 =
104
+ icb = im = ini = int = ih = nil
105
+ handler = proc { |p1, p2|
106
+ invoked = true
107
+ ip1 = p1
108
+ ip2 = p2
109
+ im = @rjr_method
110
+ ini = @rjr_node_id
111
+ int = @rjr_node_type
112
+ icb = @rjr_callback
113
+ ih = @rjr_headers
114
+ }
115
+
116
+ request = Request.new :rjr_method => method,
117
+ :rjr_method_args => params,
118
+ :rjr_headers => headers,
119
+ :rjr_callback => cb,
120
+ :rjr_node_id => ni,
121
+ :rjr_node_type => nt,
122
+ :rjr_handler => handler
144
123
 
145
- it "should be convertable from json" do
146
- j = '{"json_class":"RJR::DispatcherStat","data":{"request":{"method":"foobar","method_args":["a","b"],"headers":{"foo":"bar"},"rjr_node_type":"local","rjr_node_id":"loc1"},"result":{"result":42,"error_code":null,"error_msg":null,"error_class":null}}}'
147
- s = JSON.parse(j)
148
-
149
- s.class.should == RJR::DispatcherStat
150
- s.request.method.should == 'foobar'
151
- s.request.method_args.should == ['a', 'b']
152
- s.request.headers.should == { 'foo' => 'bar' }
153
- s.request.rjr_node_type.should == 'local'
154
- s.request.rjr_node_id.should == 'loc1'
155
- s.result.result.should == 42
124
+ request.handle
125
+ invoked.should be_true
126
+ ip1.should == params[0]
127
+ ip2.should == params[1]
128
+ im.should == method
129
+ ini.should == ni
130
+ int.should == nt
131
+ icb.should == cb
132
+ ih.should == headers
133
+ end
134
+ end
156
135
  end
157
136
  end
158
137
 
159
- describe RJR::Dispatcher do
160
- it "should dispatch request to registered handler" do
161
- invoked_foobar = false
162
- invoked_barfoo = false
163
- RJR::Dispatcher.init_handlers
164
- RJR::Dispatcher.add_handler('foobar') { |param1, param2|
165
- invoked_foobar = true
166
- param1.should == "param1"
167
- param2.should == "param2"
168
- "retval"
169
- }
170
- RJR::Dispatcher.add_handler('barfoo') { |param1, param2|
171
- invoked_barfoo = true
172
- }
173
- res = RJR::Dispatcher.dispatch_request('foobar', :method_args => ['param1', 'param2'])
174
- res.success.should == true
175
- res.result.should == "retval"
176
- invoked_foobar.should == true
177
- invoked_barfoo.should == false
178
- end
138
+ module RJR
139
+ describe Dispatcher do
140
+ context "registering handlers" do
141
+ it "should load module"
179
142
 
180
- it "should allow user to determine registered handlers" do
181
- foobar = lambda {}
182
- barfoo = lambda {}
183
- RJR::Dispatcher.add_handler('foobar', &foobar)
184
- RJR::Dispatcher.add_handler('barfoo', &barfoo)
143
+ it "should register handler for method" do
144
+ d = Dispatcher.new
145
+ h = proc {}
146
+ d.handle('foobar', h)
147
+ d.handlers['foobar'].should == h
148
+ end
185
149
 
186
- RJR::Dispatcher.has_handler_for?('foobar').should be_true
187
- RJR::Dispatcher.has_handler_for?('barfoo').should be_true
188
- RJR::Dispatcher.has_handler_for?('money').should be_false
150
+ it "should set handler from block param" do
151
+ d = Dispatcher.new
152
+ h = proc {}
153
+ d.handle('foobar', &h)
154
+ d.handlers['foobar'].should == h
155
+ end
189
156
 
190
- RJR::Dispatcher.handler_for('foobar').handler_proc.should == foobar
191
- RJR::Dispatcher.handler_for('barfoo').handler_proc.should == barfoo
192
- RJR::Dispatcher.handler_for('money').should be_nil
193
- end
157
+ it "should register handler for multiple methods" do
158
+ d = Dispatcher.new
159
+ h = proc {}
160
+ d.handle(['foobar', 'barfoo'], &h)
161
+ d.handlers['foobar'].should == h
162
+ d.handlers['barfoo'].should == h
163
+ end
164
+ end
194
165
 
195
- it "should allow a single handler to be subscribed to multiple methods" do
196
- invoked_handler = 0
197
- RJR::Dispatcher.init_handlers
198
- RJR::Dispatcher.add_handler(['foobar', 'barfoo']) { |param1, param2|
199
- invoked_handler += 1
200
- }
201
- RJR::Dispatcher.dispatch_request('foobar', :method_args => ['param1', 'param2'])
202
- RJR::Dispatcher.dispatch_request('barfoo', :method_args => ['param1', 'param2'])
203
- invoked_handler.should == 2
204
- end
166
+ context "dispatching requests" do
167
+ context "handler does not exist" do
168
+ it "should return method not found" do
169
+ d = Dispatcher.new
170
+ r = d.dispatch :rjr_method => 'foobar'
171
+ r.should == Result.method_not_found('foobar')
172
+ end
173
+ end
205
174
 
206
- it "should return method not found result if handler for specified message is missing" do
207
- RJR::Dispatcher.init_handlers
208
- res = RJR::Dispatcher.dispatch_request('foobar')
209
- res.should == RJR::Result.method_not_found('foobar')
210
- end
175
+ context "handler is registered" do
176
+ it "should invoke handler" do
177
+ invoked = false
178
+ d = Dispatcher.new
179
+ h = proc { invoked = true }
180
+ d.handle('foobar', &h)
211
181
 
212
- it "should handle success response" do
213
- res = RJR::Result.new :result => 'woot'
214
- processed = RJR::Dispatcher.handle_response(res)
215
- processed.should == "woot"
216
- end
182
+ d.dispatch :rjr_method => 'foobar'
183
+ invoked.should be_true
184
+ end
217
185
 
218
- it "should handle error response" do
219
- lambda{
220
- res = RJR::Result.new :error_code => 123, :error_msg => "bah", :error_class => ArgumentError
221
- RJR::Dispatcher.handle_response(res)
222
- }.should raise_error(Exception, "bah")
223
- #}.should raise_error(ArgumentError, "bah")
224
- end
225
- end
186
+ it "should pass params to handler" do
187
+ param = nil
188
+ d = Dispatcher.new
189
+ h = proc { |p| param = p}
190
+ d.handle('foobar', &h)
191
+
192
+ d.dispatch(:rjr_method => 'foobar', :rjr_method_args => [42])
193
+ param.should == 42
194
+ end
195
+
196
+ it "should return request result" do
197
+ d = Dispatcher.new
198
+ h = proc { 42 }
199
+ d.handle('foobar', &h)
200
+
201
+ r = d.dispatch :rjr_method => 'foobar'
202
+ r.result.should == 42
203
+ end
204
+
205
+ it "should return request error" do
206
+ d = Dispatcher.new
207
+ h = proc { raise ArgumentError, "bah" }
208
+ d.handle('foobar', &h)
209
+
210
+ r = d.dispatch :rjr_method => 'foobar'
211
+ r.error_code.should == -32000
212
+ r.error_msg.should == "bah"
213
+ r.error_class.should == ArgumentError
214
+ end
215
+
216
+ it "should register request" do
217
+ d = Dispatcher.new
218
+ h = proc {}
219
+ d.handle('foobar', &h)
220
+
221
+ d.requests.size.should == 0
222
+ d.dispatch :rjr_method => 'foobar'
223
+ d.requests.size.should == 1
224
+ d.requests.first.rjr_method.should == 'foobar'
225
+ end
226
+
227
+ it "should set params on request" do
228
+ d = Dispatcher.new
229
+ h = proc { |p| }
230
+ d.handle('foobar', &h)
231
+
232
+ d.dispatch(:rjr_method => 'foobar', :rjr_method_args => [42])
233
+ d.requests.first.rjr_method_args.should == [42]
234
+ end
235
+
236
+ it "should set result on request" do
237
+ d = Dispatcher.new
238
+ h = proc { 42 }
239
+ d.handle('foobar', &h)
240
+
241
+ d.dispatch :rjr_method => 'foobar'
242
+ d.requests.first.result.result.should == 42
243
+ end
244
+ end
245
+ end
246
+
247
+ context "processing responses" do
248
+ context "successful response" do
249
+ it "should return result" do
250
+ r = Result.new :result => 'woot'
251
+ d = Dispatcher.new
252
+ p = d.handle_response(r)
253
+ p.should == "woot"
254
+ end
255
+ end
256
+
257
+ context "failed response" do
258
+ it "should raise error" do
259
+ r = Result.new :error_code => 123, :error_msg => "bah",
260
+ :error_class => ArgumentError
261
+ d = Dispatcher.new
262
+ lambda{
263
+ d.handle_response(r)
264
+ }.should raise_error(Exception, "bah")
265
+ #}.should raise_error(ArgumentError, "bah")
266
+ end
267
+ end
268
+ end
269
+
270
+ end # describe Dispatcher
271
+ end # module RJR
@@ -1,85 +1,57 @@
1
- require 'rjr/dispatcher'
1
+ require 'thread'
2
2
  require 'rjr/em_adapter'
3
3
 
4
- describe EMManager do
5
- it "should start and halt the reactor thread" do
6
- manager = EMManager.new
7
- manager.start
8
- EventMachine.reactor_running?.should be_true
9
- manager.running?.should be_true
10
- manager.instance_variable_get(:@reactor_thread).should_not be_nil
11
- rt = manager.instance_variable_get(:@reactor_thread)
12
- ['sleep', 'run'].should include(manager.instance_variable_get(:@reactor_thread).status)
4
+ module RJR
5
+ describe EMAdapter do
6
+ after(:each) do
7
+ EMAdapter.instance.halt
8
+ EMAdapter.instance.join
9
+ end
10
+
11
+ it "should be a singleton" do
12
+ em = EMAdapter.instance
13
+ EMAdapter.instance.should == em
14
+ end
15
+
16
+ it "should start the reactor" do
17
+ em = EMAdapter.instance
18
+ em.start
19
+ em.reactor_running?.should be_true
20
+ ['sleep', 'run'].should include(em.reactor_thread.status)
21
+ end
22
+
23
+ it "should only start the reactor once" do
24
+ em = EMAdapter.instance
25
+ em.start
26
+
27
+ ot = em.reactor_thread
28
+ em.start
29
+ em.reactor_thread.should == ot
30
+ end
31
+
32
+ it "should halt the reactor" do
33
+ em = EMAdapter.instance
34
+ em.start
35
+
36
+ em.halt
37
+ em.join
38
+ em.reactor_running?.should be_false
39
+ em.reactor_thread.should be_nil
40
+ end
41
+
42
+ it "should dispatch all requests to eventmachine" do
43
+ em = EMAdapter.instance
44
+ em.start
45
+
46
+ invoked = false
47
+ m,c = Mutex.new, ConditionVariable.new
48
+ em.schedule {
49
+ invoked = true
50
+ m.synchronize { c.signal }
51
+ }
52
+ m.synchronize { c.wait m, 0.5 } if !invoked
53
+ invoked.should be_true
54
+ end
13
55
 
14
- manager.start
15
- rt2 = manager.instance_variable_get(:@reactor_thread)
16
- rt.should == rt2
17
-
18
- manager.halt
19
- manager.join
20
- EventMachine.reactor_running?.should be_false
21
- manager.running?.should be_false
22
- manager.instance_variable_get(:@reactor_thread).should be_nil
23
- end
24
-
25
- it "should allow the user to schedule jobs" do
26
- manager = EMManager.new
27
- manager.start
28
- manager.running?.should be_true
29
- block_ran = false
30
- manager.schedule {
31
- block_ran = true
32
- }
33
- sleep 0.5
34
- block_ran.should == true
35
-
36
- manager.halt
37
- manager.join
38
- manager.running?.should be_false
39
- end
40
-
41
- it "should allow the user to keep the reactor alive until forcibly stopped" do
42
- manager = EMManager.new
43
- manager.start
44
- manager.running?.should be_true
45
- manager.schedule { "foo" }
46
-
47
- manager.running?.should be_true
48
-
49
- # forcibly stop the reactor
50
- manager.halt
51
- manager.join
52
- manager.running?.should be_false
53
- end
54
-
55
- it "should allow the user to schedule at job after a specified interval" do
56
- manager = EMManager.new
57
- manager.start
58
- manager.running?.should be_true
59
- block_called = false
60
- manager.add_timer(1) { block_called = true }
61
- sleep 0.5
62
- block_called.should == false
63
- sleep 1
64
- block_called.should == true
65
- manager.halt
66
- manager.join
67
- end
68
-
69
- it "should allow the user to schedule at job repeatidly with a specified interval" do
70
- manager = EMManager.new
71
- manager.start
72
- manager.running?.should be_true
73
- times_block_called = 0
74
- manager.add_periodic_timer(1) { times_block_called += 1 }
75
- sleep 0.6
76
- times_block_called.should == 0
77
- sleep 0.6
78
- times_block_called.should == 1
79
- sleep 1.2
80
- times_block_called.should == 2
81
-
82
- manager.halt
83
- manager.join
84
56
  end
85
57
  end