celluloid 0.14.1 → 0.15.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/lib/celluloid.rb +92 -108
- data/lib/celluloid/actor.rb +42 -64
- data/lib/celluloid/autostart.rb +1 -1
- data/lib/celluloid/call_chain.rb +13 -0
- data/lib/celluloid/calls.rb +5 -8
- data/lib/celluloid/condition.rb +8 -10
- data/lib/celluloid/cpu_counter.rb +1 -1
- data/lib/celluloid/evented_mailbox.rb +7 -10
- data/lib/celluloid/fsm.rb +1 -1
- data/lib/celluloid/future.rb +1 -2
- data/lib/celluloid/internal_pool.rb +77 -20
- data/lib/celluloid/legacy.rb +0 -38
- data/lib/celluloid/mailbox.rb +17 -10
- data/lib/celluloid/pool_manager.rb +1 -1
- data/lib/celluloid/properties.rb +24 -0
- data/lib/celluloid/proxies/abstract_proxy.rb +3 -0
- data/lib/celluloid/proxies/actor_proxy.rb +3 -32
- data/lib/celluloid/proxies/async_proxy.rb +4 -8
- data/lib/celluloid/proxies/future_proxy.rb +8 -6
- data/lib/celluloid/proxies/sync_proxy.rb +12 -7
- data/lib/celluloid/rspec.rb +3 -1
- data/lib/celluloid/signals.rb +7 -35
- data/lib/celluloid/stack_dump.rb +50 -37
- data/lib/celluloid/supervision_group.rb +5 -5
- data/lib/celluloid/task_set.rb +49 -0
- data/lib/celluloid/tasks.rb +67 -42
- data/lib/celluloid/tasks/task_fiber.rb +3 -1
- data/lib/celluloid/tasks/task_thread.rb +2 -3
- data/lib/celluloid/thread.rb +2 -0
- data/spec/celluloid/actor_spec.rb +5 -0
- data/spec/celluloid/block_spec.rb +54 -0
- data/spec/celluloid/calls_spec.rb +42 -0
- data/spec/celluloid/condition_spec.rb +65 -0
- data/spec/celluloid/evented_mailbox_spec.rb +34 -0
- data/spec/celluloid/fsm_spec.rb +107 -0
- data/spec/celluloid/future_spec.rb +32 -0
- data/spec/celluloid/internal_pool_spec.rb +52 -0
- data/spec/celluloid/links_spec.rb +45 -0
- data/spec/celluloid/logging/ring_buffer_spec.rb +38 -0
- data/spec/celluloid/mailbox_spec.rb +5 -0
- data/spec/celluloid/notifications_spec.rb +120 -0
- data/spec/celluloid/pool_spec.rb +52 -0
- data/spec/celluloid/properties_spec.rb +42 -0
- data/spec/celluloid/registry_spec.rb +64 -0
- data/spec/celluloid/stack_dump_spec.rb +35 -0
- data/spec/celluloid/supervision_group_spec.rb +53 -0
- data/spec/celluloid/supervisor_spec.rb +92 -0
- data/spec/celluloid/tasks/task_fiber_spec.rb +5 -0
- data/spec/celluloid/tasks/task_thread_spec.rb +5 -0
- data/spec/celluloid/thread_handle_spec.rb +22 -0
- data/spec/celluloid/uuid_spec.rb +11 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/actor_examples.rb +161 -10
- data/spec/support/example_actor_class.rb +8 -0
- data/spec/support/mailbox_examples.rb +15 -3
- data/spec/support/task_examples.rb +2 -2
- metadata +28 -3
- data/lib/celluloid/version.rb +0 -4
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Celluloid::StackDump do
|
4
|
+
class BlockingActor
|
5
|
+
include Celluloid
|
6
|
+
|
7
|
+
def blocking
|
8
|
+
Kernel.sleep
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
[Celluloid::TaskFiber, Celluloid::TaskThread].each do |task_klass|
|
14
|
+
actor_klass = Class.new(BlockingActor) do
|
15
|
+
task_class task_klass
|
16
|
+
end
|
17
|
+
actor = actor_klass.new
|
18
|
+
actor.async.blocking
|
19
|
+
end
|
20
|
+
|
21
|
+
Celluloid.internal_pool.get do
|
22
|
+
Thread.current.role = :testing
|
23
|
+
sleep
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should include all actors' do
|
28
|
+
subject.actors.size.should == Celluloid::Actor.all.size
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should include threads that are not actors' do
|
32
|
+
pending "bugs"
|
33
|
+
subject.threads.size.should == 2
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Celluloid::SupervisionGroup do
|
4
|
+
before :all do
|
5
|
+
class MyActor
|
6
|
+
include Celluloid
|
7
|
+
|
8
|
+
def running?; :yep; end
|
9
|
+
end
|
10
|
+
|
11
|
+
class MyGroup < Celluloid::SupervisionGroup
|
12
|
+
supervise MyActor, :as => :example
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "runs applications" do
|
17
|
+
MyGroup.run!
|
18
|
+
sleep 0.01 # startup time hax
|
19
|
+
|
20
|
+
Celluloid::Actor[:example].should be_running
|
21
|
+
end
|
22
|
+
|
23
|
+
it "accepts a private actor registry" do
|
24
|
+
my_registry = Celluloid::Registry.new
|
25
|
+
MyGroup.run!(my_registry)
|
26
|
+
sleep 0.01
|
27
|
+
|
28
|
+
my_registry[:example].should be_running
|
29
|
+
end
|
30
|
+
|
31
|
+
context "pool" do
|
32
|
+
before :all do
|
33
|
+
class MyActor
|
34
|
+
attr_reader :args
|
35
|
+
def initialize *args
|
36
|
+
@args = *args
|
37
|
+
end
|
38
|
+
end
|
39
|
+
class MyGroup
|
40
|
+
pool MyActor, :as => :example_pool, :args => 'foo', :size => 3
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "runs applications and passes pool options and actor args" do
|
45
|
+
MyGroup.run!
|
46
|
+
sleep 0.001 # startup time hax
|
47
|
+
|
48
|
+
Celluloid::Actor[:example_pool].should be_running
|
49
|
+
Celluloid::Actor[:example_pool].args.should eq ['foo']
|
50
|
+
Celluloid::Actor[:example_pool].size.should be 3
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Celluloid::Supervisor do
|
4
|
+
class SubordinateDead < StandardError; end
|
5
|
+
|
6
|
+
class Subordinate
|
7
|
+
include Celluloid
|
8
|
+
attr_reader :state
|
9
|
+
|
10
|
+
def initialize(state)
|
11
|
+
@state = state
|
12
|
+
end
|
13
|
+
|
14
|
+
def crack_the_whip
|
15
|
+
case @state
|
16
|
+
when :idle
|
17
|
+
@state = :working
|
18
|
+
else raise SubordinateDead, "the spec purposely crashed me :("
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "restarts actors when they die" do
|
24
|
+
supervisor = Celluloid::Supervisor.supervise(Subordinate, :idle)
|
25
|
+
subordinate = supervisor.actors.first
|
26
|
+
subordinate.state.should be(:idle)
|
27
|
+
|
28
|
+
subordinate.crack_the_whip
|
29
|
+
subordinate.state.should be(:working)
|
30
|
+
|
31
|
+
expect do
|
32
|
+
subordinate.crack_the_whip
|
33
|
+
end.to raise_exception(SubordinateDead)
|
34
|
+
sleep 0.1 # hax to prevent race :(
|
35
|
+
subordinate.should_not be_alive
|
36
|
+
|
37
|
+
new_subordinate = supervisor.actors.first
|
38
|
+
new_subordinate.should_not eq subordinate
|
39
|
+
new_subordinate.state.should eq :idle
|
40
|
+
end
|
41
|
+
|
42
|
+
it "registers actors and reregisters them when they die" do
|
43
|
+
Celluloid::Supervisor.supervise_as(:subordinate, Subordinate, :idle)
|
44
|
+
subordinate = Celluloid::Actor[:subordinate]
|
45
|
+
subordinate.state.should be(:idle)
|
46
|
+
|
47
|
+
subordinate.crack_the_whip
|
48
|
+
subordinate.state.should be(:working)
|
49
|
+
|
50
|
+
expect do
|
51
|
+
subordinate.crack_the_whip
|
52
|
+
end.to raise_exception(SubordinateDead)
|
53
|
+
sleep 0.1 # hax to prevent race :(
|
54
|
+
subordinate.should_not be_alive
|
55
|
+
|
56
|
+
new_subordinate = Celluloid::Actor[:subordinate]
|
57
|
+
new_subordinate.should_not eq subordinate
|
58
|
+
new_subordinate.state.should eq :idle
|
59
|
+
end
|
60
|
+
|
61
|
+
it "creates supervisors via Actor.supervise" do
|
62
|
+
supervisor = Subordinate.supervise(:working)
|
63
|
+
subordinate = supervisor.actors.first
|
64
|
+
subordinate.state.should be(:working)
|
65
|
+
|
66
|
+
expect do
|
67
|
+
subordinate.crack_the_whip
|
68
|
+
end.to raise_exception(SubordinateDead)
|
69
|
+
sleep 0.1 # hax to prevent race :(
|
70
|
+
subordinate.should_not be_alive
|
71
|
+
|
72
|
+
new_subordinate = supervisor.actors.first
|
73
|
+
new_subordinate.should_not eq subordinate
|
74
|
+
new_subordinate.state.should eq :working
|
75
|
+
end
|
76
|
+
|
77
|
+
it "creates supervisors and registers actors via Actor.supervise_as" do
|
78
|
+
supervisor = Subordinate.supervise_as(:subordinate, :working)
|
79
|
+
subordinate = Celluloid::Actor[:subordinate]
|
80
|
+
subordinate.state.should be(:working)
|
81
|
+
|
82
|
+
expect do
|
83
|
+
subordinate.crack_the_whip
|
84
|
+
end.to raise_exception(SubordinateDead)
|
85
|
+
sleep 0.1 # hax to prevent race :(
|
86
|
+
subordinate.should_not be_alive
|
87
|
+
|
88
|
+
new_subordinate = supervisor.actors.first
|
89
|
+
new_subordinate.should_not eq subordinate
|
90
|
+
new_subordinate.state.should be(:working)
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Celluloid::ThreadHandle do
|
4
|
+
it "knows thread liveliness" do
|
5
|
+
queue = Queue.new
|
6
|
+
handle = Celluloid::ThreadHandle.new { queue.pop }
|
7
|
+
handle.should be_alive
|
8
|
+
|
9
|
+
queue << :die
|
10
|
+
|
11
|
+
sleep 0.01 # hax
|
12
|
+
handle.should_not be_alive
|
13
|
+
end
|
14
|
+
|
15
|
+
it "joins to thread handles" do
|
16
|
+
Celluloid::ThreadHandle.new { sleep 0.01 }.join
|
17
|
+
end
|
18
|
+
|
19
|
+
it "supports passing a role" do
|
20
|
+
Celluloid::ThreadHandle.new(:useful) { Thread.current.role.should == :useful }.join
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Celluloid::UUID do
|
4
|
+
U = Celluloid::UUID
|
5
|
+
|
6
|
+
it "generates unique IDs across the BLOCK_SIZE boundary" do
|
7
|
+
upper_bound = U::BLOCK_SIZE * 2 + 10
|
8
|
+
uuids = (1..upper_bound).map{ U.generate }
|
9
|
+
uuids.size.should == uuids.uniq.size
|
10
|
+
end
|
11
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear!
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'celluloid'
|
7
|
+
require 'celluloid/rspec'
|
8
|
+
|
9
|
+
logfile = File.open(File.expand_path("../../log/test.log", __FILE__), 'a')
|
10
|
+
logfile.sync = true
|
11
|
+
|
12
|
+
logger = Celluloid.logger = Logger.new(logfile)
|
13
|
+
|
14
|
+
Celluloid.shutdown_timeout = 1
|
15
|
+
|
16
|
+
Dir['./spec/support/*.rb'].map {|f| require f }
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.filter_run :focus => true
|
20
|
+
config.run_all_when_everything_filtered = true
|
21
|
+
|
22
|
+
config.before do
|
23
|
+
Celluloid.logger = logger
|
24
|
+
Celluloid.shutdown
|
25
|
+
sleep 0.01
|
26
|
+
|
27
|
+
Celluloid.internal_pool.assert_inactive
|
28
|
+
|
29
|
+
Celluloid.boot
|
30
|
+
end
|
31
|
+
end
|
@@ -34,6 +34,11 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
34
34
|
actor.object_id.should_not eq(Kernel.object_id)
|
35
35
|
end
|
36
36
|
|
37
|
+
it "implements respond_to? correctly" do
|
38
|
+
actor = actor_class.new 'Troy McClure'
|
39
|
+
actor.should respond_to(:alive?)
|
40
|
+
end
|
41
|
+
|
37
42
|
it "supports synchronous calls" do
|
38
43
|
actor = actor_class.new "Troy McClure"
|
39
44
|
actor.greet.should eq("Hi, I'm Troy McClure")
|
@@ -91,6 +96,36 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
91
96
|
ponycopter.greet_by_proxy(actor).should eq("Hi, I'm a ponycopter!")
|
92
97
|
end
|
93
98
|
|
99
|
+
it "detects recursion" do
|
100
|
+
klass1 = Class.new do
|
101
|
+
include included_module
|
102
|
+
task_class task_klass
|
103
|
+
|
104
|
+
def recursion_test(recurse_through = nil)
|
105
|
+
if recurse_through
|
106
|
+
recurse_through.recursion_thunk(Celluloid::Actor.current)
|
107
|
+
else
|
108
|
+
Celluloid.detect_recursion
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
klass2 = Class.new do
|
114
|
+
include included_module
|
115
|
+
task_class task_klass
|
116
|
+
|
117
|
+
def recursion_thunk(other)
|
118
|
+
other.recursion_test
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
actor1 = klass1.new
|
123
|
+
actor2 = klass2.new
|
124
|
+
|
125
|
+
actor1.recursion_test.should be_false
|
126
|
+
actor1.recursion_test(actor2).should be_true
|
127
|
+
end
|
128
|
+
|
94
129
|
it "properly handles method_missing" do
|
95
130
|
actor = actor_class.new "Method Missing"
|
96
131
|
actor.should respond_to(:first)
|
@@ -103,6 +138,24 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
103
138
|
actor.respond_to?(:zomg_private, true).should be_true
|
104
139
|
end
|
105
140
|
|
141
|
+
it "warns about suspending the initialize" do
|
142
|
+
klass = Class.new do
|
143
|
+
include included_module
|
144
|
+
task_class task_klass
|
145
|
+
|
146
|
+
def initialize
|
147
|
+
sleep 0.1
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
Celluloid.logger = double.as_null_object
|
152
|
+
Celluloid.logger.should_receive(:warn).with(/Dangerously suspending task: type=:call, meta={:method_name=>:initialize}, status=:sleeping/)
|
153
|
+
|
154
|
+
actor = klass.new
|
155
|
+
actor.terminate
|
156
|
+
Celluloid::Actor.join(actor) unless defined?(JRUBY_VERSION)
|
157
|
+
end
|
158
|
+
|
106
159
|
it "calls the user defined finalizer" do
|
107
160
|
actor = actor_class.new "Mr. Bean"
|
108
161
|
actor.wrapped_object.should_receive(:my_finalizer)
|
@@ -110,6 +163,26 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
110
163
|
Celluloid::Actor.join(actor)
|
111
164
|
end
|
112
165
|
|
166
|
+
it "warns about suspending the finalizer" do
|
167
|
+
klass = Class.new do
|
168
|
+
include included_module
|
169
|
+
task_class task_klass
|
170
|
+
|
171
|
+
finalizer :cleanup
|
172
|
+
|
173
|
+
def cleanup
|
174
|
+
sleep 0.1
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
Celluloid.logger = double.as_null_object
|
179
|
+
Celluloid.logger.should_receive(:warn).with(/Dangerously suspending task: type=:finalizer, meta={:method_name=>:cleanup}, status=:sleeping/)
|
180
|
+
|
181
|
+
actor = klass.new
|
182
|
+
actor.terminate
|
183
|
+
Celluloid::Actor.join(actor)
|
184
|
+
end
|
185
|
+
|
113
186
|
it "supports async(:method) syntax for asynchronous calls" do
|
114
187
|
actor = actor_class.new "Troy McClure"
|
115
188
|
actor.async :change_name, "Charlie Sheen"
|
@@ -162,6 +235,27 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
162
235
|
actor.inspect.should include('dead')
|
163
236
|
end
|
164
237
|
|
238
|
+
it "supports recursive inspect with other actors" do
|
239
|
+
klass = Class.new do
|
240
|
+
include included_module
|
241
|
+
task_class task_klass
|
242
|
+
|
243
|
+
attr_accessor :other
|
244
|
+
|
245
|
+
def initialize(other = nil)
|
246
|
+
@other = other
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
itchy = klass.new
|
251
|
+
scratchy = klass.new(itchy)
|
252
|
+
itchy.other = scratchy
|
253
|
+
|
254
|
+
inspection = itchy.inspect
|
255
|
+
inspection.should match(/Celluloid::ActorProxy\(/)
|
256
|
+
inspection.should include("...")
|
257
|
+
end
|
258
|
+
|
165
259
|
it "allows access to the wrapped object" do
|
166
260
|
actor = actor_class.new "Troy McClure"
|
167
261
|
actor.wrapped_object.should be_a actor_class
|
@@ -239,6 +333,8 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
239
333
|
actor = actor_class.new "James Dean"
|
240
334
|
actor.crash rescue nil
|
241
335
|
|
336
|
+
sleep 0.1 # hax to prevent a race between exit handling and the next call
|
337
|
+
|
242
338
|
expect do
|
243
339
|
actor.greet
|
244
340
|
end.to raise_exception(Celluloid::DeadActorError)
|
@@ -283,6 +379,14 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
283
379
|
actor.should_not be_alive
|
284
380
|
end
|
285
381
|
|
382
|
+
it "can be terminated by a SyncCall" do
|
383
|
+
actor = actor_class.new "Arnold Schwarzenegger"
|
384
|
+
actor.should be_alive
|
385
|
+
actor.shutdown
|
386
|
+
Celluloid::Actor.join(actor)
|
387
|
+
actor.should_not be_alive
|
388
|
+
end
|
389
|
+
|
286
390
|
it "kills" do # THOU SHALT ALWAYS KILL
|
287
391
|
actor = actor_class.new "Woody Harrelson"
|
288
392
|
actor.should be_alive
|
@@ -308,6 +412,17 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
308
412
|
actor.terminate!
|
309
413
|
end.to raise_exception(Celluloid::DeadActorError, "actor already terminated")
|
310
414
|
end
|
415
|
+
|
416
|
+
it "logs a warning when terminating tasks" do
|
417
|
+
Celluloid.logger = double.as_null_object
|
418
|
+
Celluloid.logger.should_receive(:warn).with("Terminating task: type=:call, meta={:method_name=>:sleepy}, status=:sleeping")
|
419
|
+
|
420
|
+
actor = actor_class.new "Arnold Schwarzenegger"
|
421
|
+
actor.async.sleepy 10
|
422
|
+
actor.greet # make sure the actor has started sleeping
|
423
|
+
|
424
|
+
actor.terminate
|
425
|
+
end
|
311
426
|
end
|
312
427
|
|
313
428
|
context :current_actor do
|
@@ -438,8 +553,6 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
438
553
|
raise "already signaled" if @signaled
|
439
554
|
|
440
555
|
@waiting = true
|
441
|
-
signal :future
|
442
|
-
|
443
556
|
value = wait :ponycopter
|
444
557
|
|
445
558
|
@waiting = false
|
@@ -447,11 +560,6 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
447
560
|
value
|
448
561
|
end
|
449
562
|
|
450
|
-
def wait_for_future
|
451
|
-
return true if @waiting
|
452
|
-
wait :future
|
453
|
-
end
|
454
|
-
|
455
563
|
def send_signal(value)
|
456
564
|
signal :ponycopter, value
|
457
565
|
end
|
@@ -467,9 +575,11 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
467
575
|
|
468
576
|
obj.async.wait_for_signal
|
469
577
|
obj.should_not be_signaled
|
578
|
+
obj.should be_waiting
|
470
579
|
|
471
580
|
obj.send_signal :foobar
|
472
581
|
obj.should be_signaled
|
582
|
+
obj.should_not be_waiting
|
473
583
|
end
|
474
584
|
|
475
585
|
it "sends values along with signals" do
|
@@ -478,7 +588,6 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
478
588
|
|
479
589
|
future = obj.future(:wait_for_signal)
|
480
590
|
|
481
|
-
obj.wait_for_future
|
482
591
|
obj.should be_waiting
|
483
592
|
obj.should_not be_signaled
|
484
593
|
|
@@ -799,12 +908,12 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
799
908
|
end
|
800
909
|
end
|
801
910
|
|
802
|
-
context :
|
911
|
+
context :mailbox_size do
|
803
912
|
subject do
|
804
913
|
Class.new do
|
805
914
|
include included_module
|
806
915
|
task_class task_klass
|
807
|
-
|
916
|
+
mailbox_size 100
|
808
917
|
end
|
809
918
|
end
|
810
919
|
|
@@ -857,4 +966,46 @@ shared_examples "Celluloid::Actor examples" do |included_module, task_klass|
|
|
857
966
|
subclass.new.tasks.first.should be_a ExampleTask
|
858
967
|
end
|
859
968
|
end
|
969
|
+
|
970
|
+
context :timeouts do
|
971
|
+
let :actor_class do
|
972
|
+
Class.new do
|
973
|
+
include included_module
|
974
|
+
|
975
|
+
def name
|
976
|
+
sleep 0.5
|
977
|
+
:foo
|
978
|
+
end
|
979
|
+
|
980
|
+
def ask_name_with_timeout(other, duration)
|
981
|
+
timeout(duration) { other.name }
|
982
|
+
end
|
983
|
+
end
|
984
|
+
end
|
985
|
+
|
986
|
+
it "allows timing out tasks, raising Celluloid::Task::TimeoutError" do
|
987
|
+
a1 = actor_class.new
|
988
|
+
a2 = actor_class.new
|
989
|
+
|
990
|
+
expect { a1.ask_name_with_timeout a2, 0.3 }.to raise_error(Celluloid::Task::TimeoutError)
|
991
|
+
end
|
992
|
+
|
993
|
+
it "does not raise when it completes in time" do
|
994
|
+
a1 = actor_class.new
|
995
|
+
a2 = actor_class.new
|
996
|
+
|
997
|
+
a1.ask_name_with_timeout(a2, 0.6).should == :foo
|
998
|
+
end
|
999
|
+
end
|
1000
|
+
|
1001
|
+
context "raw message sends" do
|
1002
|
+
it "logs on unhandled messages" do
|
1003
|
+
Celluloid.logger = double.as_null_object
|
1004
|
+
Celluloid.logger.should_receive(:debug).with("Discarded message (unhandled): first")
|
1005
|
+
|
1006
|
+
actor = actor_class.new "Irma Gladden"
|
1007
|
+
actor.mailbox << :first
|
1008
|
+
sleep Celluloid::TIMER_QUANTUM
|
1009
|
+
end
|
1010
|
+
end
|
860
1011
|
end
|