celluloid 0.12.4 → 0.13.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  module Celluloid
2
2
  # Method handles that route through an actor proxy
3
3
  class Method
4
+
4
5
  def initialize(actor, name)
5
6
  raise NameError, "undefined method `#{name}'" unless actor.respond_to? name
6
7
 
@@ -8,6 +9,10 @@ module Celluloid
8
9
  @klass = @actor.class
9
10
  end
10
11
 
12
+ def arity
13
+ @actor._send_(:method, @name).arity
14
+ end
15
+
11
16
  def call(*args, &block)
12
17
  @actor._send_(@name, *args, &block)
13
18
  end
@@ -6,7 +6,8 @@ module Celluloid
6
6
  # Don't use this class directly. Instead use MyKlass.pool
7
7
  class PoolManager
8
8
  include Celluloid
9
- trap_exit :crash_handler
9
+ trap_exit :__crash_handler__
10
+ finalizer :__shutdown__
10
11
 
11
12
  def initialize(worker_class, options = {})
12
13
  @size = options[:size] || [Celluloid.cores, 2].max
@@ -22,7 +23,7 @@ module Celluloid
22
23
  @busy = []
23
24
  end
24
25
 
25
- def finalize
26
+ def __shutdown__
26
27
  terminators = (@idle + @busy).each do |actor|
27
28
  begin
28
29
  actor.future(:terminate)
@@ -34,13 +35,13 @@ module Celluloid
34
35
  end
35
36
 
36
37
  def _send_(method, *args, &block)
37
- worker = __provision_worker
38
+ worker = __provision_worker__
38
39
 
39
40
  begin
40
41
  worker._send_ method, *args, &block
41
42
  rescue DeadActorError # if we get a dead actor out of the pool
42
43
  wait :respawn_complete
43
- worker = __provision_worker
44
+ worker = __provision_worker__
44
45
  retry
45
46
  rescue Exception => ex
46
47
  abort ex
@@ -89,11 +90,11 @@ module Celluloid
89
90
  end
90
91
 
91
92
  # Provision a new worker
92
- def __provision_worker
93
+ def __provision_worker__
93
94
  while @idle.empty?
94
95
  # Wait for responses from one of the busy workers
95
96
  response = exclusive { receive { |msg| msg.is_a?(Response) } }
96
- Thread.current[:actor].handle_message(response)
97
+ Thread.current[:celluloid_actor].handle_message(response)
97
98
  end
98
99
 
99
100
  worker = @idle.shift
@@ -103,7 +104,7 @@ module Celluloid
103
104
  end
104
105
 
105
106
  # Spawn a new worker for every crashed one
106
- def crash_handler(actor, reason)
107
+ def __crash_handler__(actor, reason)
107
108
  @busy.delete actor
108
109
  @idle.delete actor
109
110
  return unless reason
@@ -18,6 +18,10 @@ module Celluloid
18
18
  Actor.call @mailbox, :__send__, :class
19
19
  end
20
20
 
21
+ def send(meth, *args, &block)
22
+ Actor.call @mailbox, :send, meth, *args, &block
23
+ end
24
+
21
25
  def _send_(meth, *args, &block)
22
26
  Actor.call @mailbox, :__send__, meth, *args, &block
23
27
  end
@@ -93,14 +97,7 @@ module Celluloid
93
97
 
94
98
  # method_missing black magic to call bang predicate methods asynchronously
95
99
  def method_missing(meth, *args, &block)
96
- # bang methods are async calls
97
- if meth.match(/!$/)
98
- unbanged_meth = meth.to_s
99
- unbanged_meth.slice!(-1, 1)
100
- Actor.async @mailbox, unbanged_meth, *args, &block
101
- else
102
- Actor.call @mailbox, meth, *args, &block
103
- end
100
+ Actor.call @mailbox, meth, *args, &block
104
101
  end
105
102
  end
106
103
  end
@@ -13,7 +13,11 @@ module Celluloid
13
13
 
14
14
  # method_missing black magic to call bang predicate methods asynchronously
15
15
  def method_missing(meth, *args, &block)
16
- Actor.async @mailbox, meth, *args, &block
16
+ if @mailbox == ::Thread.current[:celluloid_mailbox]
17
+ Actor.async @mailbox, :__send__, meth, *args, &block
18
+ else
19
+ Actor.async @mailbox, meth, *args, &block
20
+ end
17
21
  end
18
22
  end
19
23
  end
@@ -18,13 +18,15 @@ module Celluloid
18
18
  # Call was aborted due to caller error
19
19
  class ErrorResponse < Response
20
20
  def value
21
- if super.is_a? AbortError
22
- # Aborts are caused by caller error, so ensure they capture the
23
- # caller's backtrace instead of the receiver's
24
- raise super.cause.exception
25
- else
26
- raise super
21
+ ex = super
22
+ ex = ex.cause if ex.is_a? AbortError
23
+
24
+ if ex.backtrace
25
+ ex.backtrace << "(celluloid):0:in `remote procedure call'"
26
+ ex.backtrace.concat(caller)
27
27
  end
28
+
29
+ raise ex
28
30
  end
29
31
  end
30
32
  end
@@ -0,0 +1,86 @@
1
+ module Celluloid
2
+ class StackDump
3
+
4
+ class TaskState < Struct.new(:task_class, :status)
5
+ end
6
+
7
+ class ActorState
8
+ attr_accessor :subject_id, :subject_class, :name
9
+ attr_accessor :status, :tasks
10
+ attr_accessor :backtrace
11
+ end
12
+
13
+ class ThreadState < Struct.new(:thread_id, :backtrace)
14
+ end
15
+
16
+ attr_accessor :actors, :threads
17
+
18
+ def initialize
19
+ @actors = []
20
+ @threads = []
21
+
22
+ snapshot
23
+ end
24
+
25
+ def snapshot
26
+ Thread.list.each do |thread|
27
+ if actor = thread[:celluloid_actor]
28
+ @actors << snapshot_actor(actor)
29
+ else
30
+ @threads << snapshot_thread(thread)
31
+ end
32
+ end
33
+ end
34
+
35
+ def snapshot_actor(actor)
36
+ state = ActorState.new
37
+ state.subject_id = actor.subject.object_id
38
+ state.subject_class = actor.subject.class
39
+
40
+ tasks = actor.tasks
41
+ if tasks.empty?
42
+ state.status = :idle
43
+ else
44
+ state.status = :running
45
+ state.tasks = tasks.collect { |t| TaskState.new(t.class, t.status) }
46
+ end
47
+
48
+ state.backtrace = actor.thread.backtrace if actor.thread
49
+ state
50
+ end
51
+
52
+ def snapshot_thread(thread)
53
+ ThreadState.new(thread.object_id, thread.backtrace)
54
+ end
55
+
56
+ def dump(output = STDERR)
57
+ @actors.each do |actor|
58
+ output << "Celluloid::Actor 0x#{actor.subject_id.to_s(16)}: #{actor.subject_class}"
59
+ output << " [#{actor.name}]" if actor.name
60
+ output << "\n"
61
+
62
+ if actor.status == :idle
63
+ output << "State: Idle (waiting for messages)\n"
64
+ else
65
+ output << "State: Running (executing tasks)\n"
66
+ output << "Tasks:\n"
67
+
68
+ actor.tasks.each_with_index do |task, i|
69
+ output << " #{i+1}) #{task.task_class}: #{task.status}\n"
70
+ end
71
+ end
72
+
73
+ display_backtrace actor.backtrace, output
74
+ end
75
+
76
+ @threads.each do |thread|
77
+ output << "Thread 0x#{thread.thread_id.to_s(16)}:\n"
78
+ display_backtrace thread.backtrace, output
79
+ end
80
+ end
81
+
82
+ def display_backtrace(backtrace, output)
83
+ output << "\t" << backtrace.join("\n\t") << "\n\n"
84
+ end
85
+ end
86
+ end
@@ -86,9 +86,11 @@ module Celluloid
86
86
  @members.map(&:actor)
87
87
  end
88
88
 
89
+ finalizer :finalize
90
+
89
91
  # Terminate the group
90
92
  def finalize
91
- @members.each(&:terminate)
93
+ @members.reverse_each(&:terminate)
92
94
  end
93
95
 
94
96
  # Restart a crashed actor
@@ -147,7 +149,7 @@ module Celluloid
147
149
 
148
150
  def terminate
149
151
  @actor.terminate if @actor
150
- rescue DeadActorError
152
+ rescue DeadActorError, MailboxError
151
153
  end
152
154
  end
153
155
  end
@@ -51,4 +51,15 @@ module Celluloid
51
51
 
52
52
  # Request for an actor to terminate
53
53
  class TerminationRequest < SystemEvent; end
54
+
55
+ # Signal a condition
56
+ class SignalConditionRequest < SystemEvent
57
+ def initialize(task, value)
58
+ @task, @value = task, value
59
+ end
60
+
61
+ def call
62
+ @task.resume(@value)
63
+ end
64
+ end
54
65
  end
@@ -1,6 +1,3 @@
1
- require 'celluloid/tasks/task_fiber'
2
- require 'celluloid/tasks/task_thread'
3
-
4
1
  module Celluloid
5
2
  # Asked to do task-related things outside a task
6
3
  class NotTaskError < StandardError; end
@@ -9,17 +6,26 @@ module Celluloid
9
6
  class DeadTaskError < StandardError; end
10
7
 
11
8
  # Tasks are interruptable/resumable execution contexts used to run methods
12
- module Task
9
+ class Task
13
10
  class TerminatedError < StandardError; end # kill a running task
14
11
 
15
12
  # Obtain the current task
16
13
  def self.current
17
- Thread.current[:task] or raise NotTaskError, "not within a task context"
14
+ Thread.current[:celluloid_task] or raise NotTaskError, "not within a task context"
18
15
  end
19
16
 
20
17
  # Suspend the running task, deferring to the scheduler
21
18
  def self.suspend(status)
22
19
  Task.current.suspend(status)
23
20
  end
21
+
22
+ # Create a new task
23
+ def initialize(type)
24
+ @type = type
25
+ @status = :new
26
+ end
24
27
  end
25
28
  end
29
+
30
+ require 'celluloid/tasks/task_fiber'
31
+ require 'celluloid/tasks/task_thread'
@@ -2,22 +2,26 @@ module Celluloid
2
2
  class FiberStackError < StandardError; end
3
3
 
4
4
  # Tasks with a Fiber backend
5
- class TaskFiber
5
+ class TaskFiber < Task
6
6
  attr_reader :type, :status
7
7
 
8
8
  # Run the given block within a task
9
9
  def initialize(type)
10
- @type = type
11
- @status = :new
10
+ super
11
+
12
+ actor = Thread.current[:celluloid_actor]
13
+ mailbox = Thread.current[:celluloid_mailbox]
14
+ chain_id = Thread.current[:celluloid_chain_id]
12
15
 
13
- actor, mailbox = Thread.current[:actor], Thread.current[:mailbox]
14
16
  raise NotActorError, "can't create tasks outside of actors" unless actor
15
17
 
16
18
  @fiber = Fiber.new do
17
19
  @status = :running
18
- Thread.current[:actor] = actor
19
- Thread.current[:mailbox] = mailbox
20
- Thread.current[:task] = self
20
+ Thread.current[:celluloid_actor] = actor
21
+ Thread.current[:celluloid_mailbox] = mailbox
22
+ Thread.current[:celluloid_task] = self
23
+ Thread.current[:celluloid_chain_id] = chain_id
24
+
21
25
  actor.tasks << self
22
26
 
23
27
  begin
@@ -1,31 +1,35 @@
1
1
  module Celluloid
2
2
  # Tasks with a Thread backend
3
- class TaskThread
3
+ class TaskThread < Task
4
4
  attr_reader :type, :status
5
5
 
6
6
  # Run the given block within a task
7
7
  def initialize(type)
8
- @type = type
9
- @status = :new
8
+ super
10
9
 
11
10
  @resume_queue = Queue.new
12
11
  @yield_mutex = Mutex.new
13
12
  @yield_cond = ConditionVariable.new
14
13
 
15
- actor, mailbox = Thread.current[:actor], Thread.current[:mailbox]
14
+ actor = Thread.current[:celluloid_actor]
15
+ mailbox = Thread.current[:celluloid_mailbox]
16
+ chain_id = Thread.current[:celluloid_chain_id]
17
+
16
18
  raise NotActorError, "can't create tasks outside of actors" unless actor
17
19
 
18
- @thread = InternalPool.get do
20
+ @thread = Celluloid.internal_pool.get do
19
21
  begin
20
- unless @resume_queue.pop.is_a?(Task::TerminatedError)
21
- @status = :running
22
- Thread.current[:actor] = actor
23
- Thread.current[:mailbox] = mailbox
24
- Thread.current[:task] = self
25
- actor.tasks << self
26
-
27
- yield
28
- end
22
+ ex = @resume_queue.pop.is_a?(Task::TerminatedError)
23
+ raise ex if ex
24
+
25
+ @status = :running
26
+ Thread.current[:celluloid_actor] = actor
27
+ Thread.current[:celluloid_mailbox] = mailbox
28
+ Thread.current[:celluloid_task] = self
29
+ Thread.current[:celluloid_chain_id] = chain_id
30
+
31
+ actor.tasks << self
32
+ yield
29
33
  rescue Task::TerminatedError
30
34
  # Task was explicitly terminated
31
35
  ensure
@@ -1,18 +1,13 @@
1
- require 'forwardable'
2
-
3
1
  module Celluloid
4
2
  # An abstraction around threads from the InternalPool which ensures we don't
5
3
  # accidentally do things to threads which have been returned to the pool,
6
4
  # such as, say, killing them
7
5
  class ThreadHandle
8
- extend Forwardable
9
- def_delegators :@thread, :backtrace
10
-
11
6
  def initialize
12
7
  @mutex = Mutex.new
13
8
  @join = ConditionVariable.new
14
9
 
15
- @thread = InternalPool.get do
10
+ @thread = Celluloid.internal_pool.get do
16
11
  begin
17
12
  yield
18
13
  ensure
@@ -40,5 +35,14 @@ module Celluloid
40
35
  @mutex.synchronize { @join.wait(@mutex) if @thread }
41
36
  self
42
37
  end
38
+
39
+ # Obtain the backtrace for this thread
40
+ def backtrace
41
+ @thread.backtrace
42
+ rescue NoMethodError
43
+ # undefined method `backtrace' for nil:NilClass
44
+ # Swallow this in case this ThreadHandle was terminated and @thread was
45
+ # set to nil
46
+ end
43
47
  end
44
48
  end
@@ -1,4 +1,4 @@
1
1
  module Celluloid
2
- VERSION = '0.12.4'
2
+ VERSION = '0.13.0.pre'
3
3
  def self.version; VERSION; end
4
4
  end
@@ -30,11 +30,27 @@ shared_context "a Celluloid Actor" do |included_module|
30
30
  actor.greet.should == "Hi, I'm Troy McClure"
31
31
  end
32
32
 
33
+ it "supports synchronous calls with blocks" do
34
+ actor = actor_class.new "Blocky Ralboa"
35
+
36
+ block_executed = false
37
+ actor.run { block_executed = true }
38
+ block_executed.should be_true
39
+ end
40
+
33
41
  it "supports synchronous calls via #method" do
34
42
  method = actor_class.new("Troy McClure").method(:greet)
35
43
  method.call.should == "Hi, I'm Troy McClure"
36
44
  end
37
45
 
46
+ it "supports #arity calls via #method" do
47
+ method = actor_class.new("Troy McClure").method(:greet)
48
+ method.arity.should == 0
49
+
50
+ method = actor_class.new("Troy McClure").method(:change_name)
51
+ method.arity.should == 1
52
+ end
53
+
38
54
  it "supports future(:method) syntax for synchronous future calls" do
39
55
  actor = actor_class.new "Troy McClure"
40
56
  future = actor.future :greet
@@ -77,75 +93,11 @@ shared_context "a Celluloid Actor" do |included_module|
77
93
  actor.respond_to?(:zomg_private, true).should be_true
78
94
  end
79
95
 
80
- it "raises NoMethodError when a nonexistent method is called" do
81
- actor = actor_class.new "Billy Bob Thornton"
82
-
83
- expect do
84
- actor.the_method_that_wasnt_there
85
- end.to raise_exception(NoMethodError)
86
- end
87
-
88
- it "reraises exceptions which occur during synchronous calls in the caller" do
89
- actor = actor_class.new "James Dean" # is this in bad taste?
90
-
91
- expect do
92
- actor.crash
93
- end.to raise_exception(ExampleCrash)
94
- end
95
-
96
- describe "when #abort is called" do
97
- it "raises exceptions in the caller but keeps running" do
98
- actor = actor_class.new "Al Pacino"
99
-
100
- e = nil
101
- line_no = nil
102
-
103
- expect do
104
- begin
105
- line_no = __LINE__; actor.crash_with_abort "You die motherfucker!", :bar
106
- rescue => ex
107
- e = ex
108
- raise
109
- end
110
- end.to raise_exception(ExampleCrash, "You die motherfucker!")
111
-
112
- e.backtrace.any? { |line| line.include?([__FILE__, line_no].join(':')) }.should be_true # Check the backtrace is appropriate to the caller
113
- e.foo.should be == :bar # Check the exception maintains instance variables
114
-
115
- actor.should be_alive
116
- end
117
-
118
- it "converts strings to runtime errors" do
119
- actor = actor_class.new "Al Pacino"
120
- expect do
121
- actor.crash_with_abort_raw "foo"
122
- end.to raise_exception(RuntimeError, "foo")
123
- end
124
-
125
- it "crashes the caller if we pass neither String nor Exception" do
126
- actor = actor_class.new "Al Pacino"
127
- expect do
128
- actor.crash_with_abort_raw 10
129
- end.to raise_exception(TypeError, "Exception object/String expected, but Fixnum received")
130
-
131
- actor.greet rescue nil # Ensure our actor has died.
132
- actor.should_not be_alive
133
- end
134
- end
135
-
136
- it "raises DeadActorError if methods are synchronously called on a dead actor" do
137
- actor = actor_class.new "James Dean"
138
- actor.crash rescue nil
139
-
140
- expect do
141
- actor.greet
142
- end.to raise_exception(Celluloid::DeadActorError)
143
- end
144
-
145
- it "supports method! syntax for asynchronous calls" do
146
- actor = actor_class.new "Troy McClure"
147
- actor.change_name! "Charlie Sheen"
148
- actor.greet.should == "Hi, I'm Charlie Sheen"
96
+ it "calls the user defined finalizer" do
97
+ actor = actor_class.new "Mr. Bean"
98
+ actor.wrapped_object.should_receive(:my_finalizer)
99
+ actor.terminate
100
+ Celluloid::Actor.join(actor)
149
101
  end
150
102
 
151
103
  it "supports async(:method) syntax for asynchronous calls" do
@@ -160,19 +112,13 @@ shared_context "a Celluloid Actor" do |included_module|
160
112
  actor.greet.should == "Hi, I'm Charlie Sheen"
161
113
  end
162
114
 
163
- it "supports method! syntax for asynchronous calls to itself" do
164
- actor = actor_class.new "Troy McClure"
165
- actor.change_name_with_a_bang "Charlie Sheen"
166
- actor.greet.should == "Hi, I'm Charlie Sheen"
167
- end
168
-
169
115
  it "supports async.method syntax for asynchronous calls to itself" do
170
116
  actor = actor_class.new "Troy McClure"
171
117
  actor.change_name_async "Charlie Sheen"
172
118
  actor.greet.should == "Hi, I'm Charlie Sheen"
173
119
  end
174
120
 
175
- it "allows an actor to call private methods asynchronously with a bang" do
121
+ it "allows an actor to call private methods asynchronously" do
176
122
  actor = actor_class.new "Troy McClure"
177
123
  actor.call_private
178
124
  actor.private_called.should be_true
@@ -188,7 +134,7 @@ shared_context "a Celluloid Actor" do |included_module|
188
134
 
189
135
  it "inspects properly" do
190
136
  actor = actor_class.new "Troy McClure"
191
- actor.inspect.should match(/Celluloid::Actor\(/)
137
+ actor.inspect.should match(/Celluloid::ActorProxy\(/)
192
138
  actor.inspect.should match(/#{actor_class}/)
193
139
  actor.inspect.should include('@name="Troy McClure"')
194
140
  actor.inspect.should_not include("@celluloid")
@@ -215,6 +161,11 @@ shared_context "a Celluloid Actor" do |included_module|
215
161
  actor.wrapped_object.inspect.should include Celluloid::BARE_OBJECT_WARNING_MESSAGE
216
162
  end
217
163
 
164
+ it "can override #send" do
165
+ actor = actor_class.new "Troy McClure"
166
+ actor.send('foo').should == 'oof'
167
+ end
168
+
218
169
  context "mocking methods" do
219
170
  let(:actor) { actor_class.new "Troy McClure" }
220
171
 
@@ -231,6 +182,82 @@ shared_context "a Celluloid Actor" do |included_module|
231
182
  end
232
183
  end
233
184
 
185
+ context :exceptions do
186
+ it "reraises exceptions which occur during synchronous calls in the caller" do
187
+ actor = actor_class.new "James Dean" # is this in bad taste?
188
+
189
+ expect do
190
+ actor.crash
191
+ end.to raise_exception(ExampleCrash)
192
+ end
193
+
194
+ it "includes both caller and receiver in exception traces" do
195
+ ExampleReceiver = Class.new do
196
+ include included_module
197
+
198
+ def receiver_method
199
+ raise ExampleCrash, "the spec purposely crashed me :("
200
+ end
201
+ end
202
+
203
+ ExampleCaller = Class.new do
204
+ include included_module
205
+
206
+ def caller_method
207
+ ExampleReceiver.new.receiver_method
208
+ end
209
+ end
210
+
211
+ ex = nil
212
+ begin
213
+ ExampleCaller.new.caller_method
214
+ rescue => ex
215
+ end
216
+
217
+ ex.should be_a ExampleCrash
218
+ ex.backtrace.grep(/`caller_method'/).should be_true
219
+ ex.backtrace.grep(/`receiver_method'/).should be_true
220
+ end
221
+
222
+ it "raises DeadActorError if methods are synchronously called on a dead actor" do
223
+ actor = actor_class.new "James Dean"
224
+ actor.crash rescue nil
225
+
226
+ expect do
227
+ actor.greet
228
+ end.to raise_exception(Celluloid::DeadActorError)
229
+ end
230
+ end
231
+
232
+ context :abort do
233
+ it "raises exceptions in the caller but keeps running" do
234
+ actor = actor_class.new "Al Pacino"
235
+
236
+ expect do
237
+ actor.crash_with_abort "You die motherfucker!", :bar
238
+ end.to raise_exception(ExampleCrash, "You die motherfucker!")
239
+
240
+ actor.should be_alive
241
+ end
242
+
243
+ it "converts strings to runtime errors" do
244
+ actor = actor_class.new "Al Pacino"
245
+ expect do
246
+ actor.crash_with_abort_raw "foo"
247
+ end.to raise_exception(RuntimeError, "foo")
248
+ end
249
+
250
+ it "crashes the caller if we pass neither String nor Exception" do
251
+ actor = actor_class.new "Al Pacino"
252
+ expect do
253
+ actor.crash_with_abort_raw 10
254
+ end.to raise_exception(TypeError, "Exception object/String expected, but Fixnum received")
255
+
256
+ actor.greet rescue nil # Ensure our actor has died.
257
+ actor.should_not be_alive
258
+ end
259
+ end
260
+
234
261
  context :termination do
235
262
  it "terminates" do
236
263
  actor = actor_class.new "Arnold Schwarzenegger"
@@ -240,7 +267,7 @@ shared_context "a Celluloid Actor" do |included_module|
240
267
  actor.should_not be_alive
241
268
  end
242
269
 
243
- it "kills" do
270
+ it "kills" do # THOU SHALT ALWAYS KILL
244
271
  actor = actor_class.new "Woody Harrelson"
245
272
  actor.should be_alive
246
273
  Celluloid::Actor.kill(actor)
@@ -270,7 +297,7 @@ shared_context "a Celluloid Actor" do |included_module|
270
297
  context :current_actor do
271
298
  it "knows the current actor" do
272
299
  actor = actor_class.new "Roger Daltrey"
273
- actor.current_actor.should == actor
300
+ actor.current_actor.should eq actor
274
301
  end
275
302
 
276
303
  it "raises NotActorError if called outside an actor" do
@@ -420,7 +447,7 @@ shared_context "a Celluloid Actor" do |included_module|
420
447
  obj = @signaler.new
421
448
  obj.should_not be_signaled
422
449
 
423
- obj.wait_for_signal!
450
+ obj.async.wait_for_signal
424
451
  obj.should_not be_signaled
425
452
 
426
453
  obj.send_signal :foobar
@@ -533,8 +560,8 @@ shared_context "a Celluloid Actor" do |included_module|
533
560
 
534
561
  it "executes two methods in an exclusive order" do
535
562
  actor = subject.new
536
- actor.eat_donuts!
537
- actor.drink_coffee!
563
+ actor.async.eat_donuts
564
+ actor.async.drink_coffee
538
565
  sleep Celluloid::TIMER_QUANTUM * 2
539
566
  actor.tasks.should == ['donuts', 'coffee']
540
567
  end
@@ -574,7 +601,6 @@ shared_context "a Celluloid Actor" do |included_module|
574
601
  end
575
602
 
576
603
  context :timers do
577
-
578
604
  before do
579
605
  @klass = Class.new do
580
606
  include included_module
@@ -716,33 +742,13 @@ shared_context "a Celluloid Actor" do |included_module|
716
742
  end
717
743
  end
718
744
 
719
- context :proxy_class do
720
- class ExampleProxy < Celluloid::ActorProxy; end
721
-
722
- subject do
723
- Class.new do
724
- include included_module
725
- proxy_class ExampleProxy
726
- end
727
- end
728
-
729
- it "uses user-specified proxy" do
730
- subject.new.__class__.should == ExampleProxy
731
- end
732
-
733
- it "retains custom proxy when subclassed" do
734
- subclass = Class.new(subject)
735
- subclass.new.__class__.should == ExampleProxy
736
- end
737
- end
738
-
739
- context :use_mailbox do
745
+ context :mailbox_class do
740
746
  class ExampleMailbox < Celluloid::Mailbox; end
741
747
 
742
748
  subject do
743
749
  Class.new do
744
750
  include included_module
745
- use_mailbox ExampleMailbox
751
+ mailbox_class ExampleMailbox
746
752
  end
747
753
  end
748
754
 
@@ -756,23 +762,23 @@ shared_context "a Celluloid Actor" do |included_module|
756
762
  end
757
763
  end
758
764
 
759
- context :mailbox_class do
760
- class ExampleMailbox < Celluloid::Mailbox; end
765
+ context :proxy_class do
766
+ class ExampleProxy < Celluloid::ActorProxy; end
761
767
 
762
768
  subject do
763
769
  Class.new do
764
770
  include included_module
765
- mailbox_class ExampleMailbox
771
+ proxy_class ExampleProxy
766
772
  end
767
773
  end
768
774
 
769
- it "overrides the mailbox class" do
770
- subject.new.mailbox.should be_a ExampleMailbox
775
+ it "uses user-specified proxy" do
776
+ subject.new.__class__.should == ExampleProxy
771
777
  end
772
778
 
773
- it "retains custom mailboxes when subclassed" do
779
+ it "retains custom proxy when subclassed" do
774
780
  subclass = Class.new(subject)
775
- subclass.new.mailbox.should be_a ExampleMailbox
781
+ subclass.new.__class__.should == ExampleProxy
776
782
  end
777
783
  end
778
784