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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 802e81b987e2d65c9d7055c2160805612db65b50
|
4
|
+
data.tar.gz: 2a2c5eaf4c8afa92a8ee3c782ffb3e6556454061
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bee45fcc9e099fcd5b61d605fa06293d9454402f65601ff789aac7c679e9f0d206a7f696a53d37fa3febeda10163dd5c2e4da1bc8dece2101bf1a3f949ca60e
|
7
|
+
data.tar.gz: c897040ce47e50088ee2c53ea8291733d2214cb127d3014558e366f8a1e58239ea232a9d7381671d99c64fcf6dca6e65b6f1d8b335a986a8779b97f875a163da
|
data/README.md
CHANGED
@@ -99,7 +99,9 @@ Installation
|
|
99
99
|
|
100
100
|
Add this line to your application's Gemfile:
|
101
101
|
|
102
|
-
|
102
|
+
```ruby
|
103
|
+
gem 'celluloid'
|
104
|
+
```
|
103
105
|
|
104
106
|
And then execute:
|
105
107
|
|
@@ -111,7 +113,9 @@ Or install it yourself as:
|
|
111
113
|
|
112
114
|
Inside of your Ruby program, require Celluloid with:
|
113
115
|
|
114
|
-
|
116
|
+
```ruby
|
117
|
+
require 'celluloid/autostart'
|
118
|
+
```
|
115
119
|
|
116
120
|
Supported Platforms
|
117
121
|
-------------------
|
data/lib/celluloid.rb
CHANGED
@@ -3,7 +3,14 @@ require 'thread'
|
|
3
3
|
require 'timeout'
|
4
4
|
require 'set'
|
5
5
|
|
6
|
+
if defined?(JRUBY_VERSION) && JRUBY_VERSION == "1.7.3"
|
7
|
+
raise "Celluloid is broken on JRuby 1.7.3. Please upgrade to 1.7.4+"
|
8
|
+
end
|
9
|
+
|
6
10
|
module Celluloid
|
11
|
+
VERSION = '0.15.0.pre'
|
12
|
+
Error = Class.new StandardError
|
13
|
+
|
7
14
|
extend self # expose all instance methods as singleton methods
|
8
15
|
|
9
16
|
# Warning message added to Celluloid objects accessed outside their actors
|
@@ -18,6 +25,24 @@ module Celluloid
|
|
18
25
|
def included(klass)
|
19
26
|
klass.send :extend, ClassMethods
|
20
27
|
klass.send :include, InstanceMethods
|
28
|
+
|
29
|
+
klass.send :extend, Properties
|
30
|
+
|
31
|
+
klass.property :mailbox_class, :default => Celluloid::Mailbox
|
32
|
+
klass.property :proxy_class, :default => Celluloid::ActorProxy
|
33
|
+
klass.property :task_class, :default => Celluloid.task_class
|
34
|
+
klass.property :mailbox_size
|
35
|
+
|
36
|
+
klass.property :execute_block_on_receiver,
|
37
|
+
:default => [:after, :every, :receive],
|
38
|
+
:multi => true
|
39
|
+
|
40
|
+
klass.property :finalizer
|
41
|
+
klass.property :exit_handler
|
42
|
+
|
43
|
+
klass.send(:define_singleton_method, :trap_exit) do |*args|
|
44
|
+
exit_handler(*args)
|
45
|
+
end
|
21
46
|
end
|
22
47
|
|
23
48
|
# Are we currently inside of an actor?
|
@@ -48,6 +73,18 @@ module Celluloid
|
|
48
73
|
end
|
49
74
|
alias_method :dump, :stack_dump
|
50
75
|
|
76
|
+
# Detect if a particular call is recursing through multiple actors
|
77
|
+
def detect_recursion
|
78
|
+
actor = Thread.current[:celluloid_actor]
|
79
|
+
return unless actor
|
80
|
+
|
81
|
+
task = Thread.current[:celluloid_task]
|
82
|
+
return unless task
|
83
|
+
|
84
|
+
chain_id = CallChain.current_id
|
85
|
+
actor.tasks.to_a.any? { |t| t != task && t.chain_id == chain_id }
|
86
|
+
end
|
87
|
+
|
51
88
|
# Define an exception handler for actor crashes
|
52
89
|
def exception_handler(&block)
|
53
90
|
Logger.exception_handler(&block)
|
@@ -63,10 +100,18 @@ module Celluloid
|
|
63
100
|
end
|
64
101
|
end
|
65
102
|
|
103
|
+
def boot
|
104
|
+
init
|
105
|
+
start
|
106
|
+
end
|
107
|
+
|
108
|
+
def init
|
109
|
+
self.internal_pool = InternalPool.new
|
110
|
+
end
|
111
|
+
|
66
112
|
# Launch default services
|
67
113
|
# FIXME: We should set up the supervision hierarchy here
|
68
|
-
def
|
69
|
-
internal_pool.reset
|
114
|
+
def start
|
70
115
|
Celluloid::Notifications::Fanout.supervise_as :notifications_fanout
|
71
116
|
Celluloid::IncidentReporter.supervise_as :default_incident_reporter, STDERR
|
72
117
|
end
|
@@ -90,11 +135,12 @@ module Celluloid
|
|
90
135
|
|
91
136
|
# Shut down all running actors
|
92
137
|
def shutdown
|
138
|
+
actors = Actor.all
|
139
|
+
|
93
140
|
Timeout.timeout(shutdown_timeout) do
|
94
141
|
internal_pool.shutdown
|
95
142
|
|
96
|
-
actors
|
97
|
-
Logger.debug "Terminating #{actors.size} actors..." if actors.size > 0
|
143
|
+
Logger.debug "Terminating #{actors.size} #{(actors.size > 1) ? 'actors' : 'actor'}..." if actors.size > 0
|
98
144
|
|
99
145
|
# Attempt to shut down the supervision tree, if available
|
100
146
|
Supervisor.root.terminate if Supervisor.root
|
@@ -103,21 +149,31 @@ module Celluloid
|
|
103
149
|
actors.each do |actor|
|
104
150
|
begin
|
105
151
|
actor.terminate!
|
106
|
-
rescue DeadActorError
|
152
|
+
rescue DeadActorError
|
107
153
|
end
|
108
154
|
end
|
109
155
|
|
110
156
|
actors.each do |actor|
|
111
157
|
begin
|
112
158
|
Actor.join(actor)
|
113
|
-
rescue DeadActorError
|
159
|
+
rescue DeadActorError
|
114
160
|
end
|
115
161
|
end
|
116
|
-
|
117
|
-
Logger.debug "Shutdown completed cleanly"
|
118
162
|
end
|
119
163
|
rescue Timeout::Error
|
120
164
|
Logger.error("Couldn't cleanly terminate all actors in #{shutdown_timeout} seconds!")
|
165
|
+
actors.each do |actor|
|
166
|
+
begin
|
167
|
+
Actor.kill(actor)
|
168
|
+
rescue DeadActorError, MailboxDead
|
169
|
+
end
|
170
|
+
end
|
171
|
+
ensure
|
172
|
+
internal_pool.kill
|
173
|
+
end
|
174
|
+
|
175
|
+
def version
|
176
|
+
VERSION
|
121
177
|
end
|
122
178
|
end
|
123
179
|
|
@@ -173,63 +229,6 @@ module Celluloid
|
|
173
229
|
Actor.join(new(*args, &block))
|
174
230
|
end
|
175
231
|
|
176
|
-
# Trap errors from actors we're linked to when they exit
|
177
|
-
def exit_handler(callback = nil)
|
178
|
-
if callback
|
179
|
-
@exit_handler = callback.to_sym
|
180
|
-
elsif defined?(@exit_handler)
|
181
|
-
@exit_handler
|
182
|
-
elsif superclass.respond_to? :exit_handler
|
183
|
-
superclass.exit_handler
|
184
|
-
end
|
185
|
-
end
|
186
|
-
alias_method :trap_exit, :exit_handler
|
187
|
-
|
188
|
-
# Define a callback to run when the actor is finalized.
|
189
|
-
def finalizer(callback = nil)
|
190
|
-
if callback
|
191
|
-
@finalizer = callback.to_sym
|
192
|
-
elsif defined?(@finalizer)
|
193
|
-
@finalizer
|
194
|
-
elsif superclass.respond_to? :finalizer
|
195
|
-
superclass.finalizer
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
# Define the mailbox class for this class
|
200
|
-
def mailbox_class(klass = nil)
|
201
|
-
if klass
|
202
|
-
mailbox.class = klass
|
203
|
-
else
|
204
|
-
mailbox.class
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def proxy_class(klass = nil)
|
209
|
-
if klass
|
210
|
-
@proxy_class = klass
|
211
|
-
elsif defined?(@proxy_class)
|
212
|
-
@proxy_class
|
213
|
-
elsif superclass.respond_to? :proxy_class
|
214
|
-
superclass.proxy_class
|
215
|
-
else
|
216
|
-
Celluloid::ActorProxy
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
# Define the default task type for this class
|
221
|
-
def task_class(klass = nil)
|
222
|
-
if klass
|
223
|
-
@task_class = klass
|
224
|
-
elsif defined?(@task_class)
|
225
|
-
@task_class
|
226
|
-
elsif superclass.respond_to? :task_class
|
227
|
-
superclass.task_class
|
228
|
-
else
|
229
|
-
Celluloid.task_class
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
232
|
# Mark methods as running exclusively
|
234
233
|
def exclusive(*methods)
|
235
234
|
if methods.empty?
|
@@ -240,55 +239,22 @@ module Celluloid
|
|
240
239
|
end
|
241
240
|
end
|
242
241
|
|
243
|
-
# Mark methods as running blocks on the receiver
|
244
|
-
def execute_block_on_receiver(*methods)
|
245
|
-
receiver_block_executions.merge methods.map(&:to_sym)
|
246
|
-
end
|
247
|
-
|
248
|
-
def receiver_block_executions
|
249
|
-
@receiver_block_executions ||= Set.new([:after, :every, :receive])
|
250
|
-
end
|
251
|
-
|
252
242
|
# Configuration options for Actor#new
|
253
243
|
def actor_options
|
254
244
|
{
|
255
|
-
:
|
245
|
+
:mailbox_class => mailbox_class,
|
246
|
+
:mailbox_size => mailbox_size,
|
256
247
|
:proxy_class => proxy_class,
|
257
248
|
:task_class => task_class,
|
258
249
|
:exit_handler => exit_handler,
|
259
250
|
:exclusive_methods => defined?(@exclusive_methods) ? @exclusive_methods : nil,
|
260
|
-
:receiver_block_executions =>
|
251
|
+
:receiver_block_executions => execute_block_on_receiver
|
261
252
|
}
|
262
253
|
end
|
263
254
|
|
264
255
|
def ===(other)
|
265
256
|
other.kind_of? self
|
266
257
|
end
|
267
|
-
|
268
|
-
def mailbox
|
269
|
-
@mailbox_factory ||= MailboxFactory.new(self)
|
270
|
-
end
|
271
|
-
|
272
|
-
class MailboxFactory
|
273
|
-
attr_accessor :class, :max_size
|
274
|
-
|
275
|
-
def initialize(actor)
|
276
|
-
@actor = actor
|
277
|
-
@class = nil
|
278
|
-
@max_size = nil
|
279
|
-
end
|
280
|
-
|
281
|
-
def build
|
282
|
-
mailbox = mailbox_class.new
|
283
|
-
mailbox.max_size = @max_size
|
284
|
-
mailbox
|
285
|
-
end
|
286
|
-
|
287
|
-
private
|
288
|
-
def mailbox_class
|
289
|
-
@class || (@actor.superclass.respond_to?(:mailbox_class) && @actor.superclass.mailbox_class) || Celluloid::Mailbox
|
290
|
-
end
|
291
|
-
end
|
292
258
|
end
|
293
259
|
|
294
260
|
# These are methods we don't want added to the Celluloid singleton but to be
|
@@ -326,6 +292,8 @@ module Celluloid
|
|
326
292
|
end
|
327
293
|
|
328
294
|
def inspect
|
295
|
+
return "..." if Celluloid.detect_recursion
|
296
|
+
|
329
297
|
str = "#<"
|
330
298
|
|
331
299
|
if leaked?
|
@@ -363,7 +331,7 @@ module Celluloid
|
|
363
331
|
|
364
332
|
# Terminate this actor
|
365
333
|
def terminate
|
366
|
-
Thread.current[:celluloid_actor].terminate
|
334
|
+
Thread.current[:celluloid_actor].proxy.terminate!
|
367
335
|
end
|
368
336
|
|
369
337
|
# Send a signal with the given name to all waiting methods
|
@@ -383,7 +351,7 @@ module Celluloid
|
|
383
351
|
|
384
352
|
# Obtain the UUID of the current call chain
|
385
353
|
def call_chain_id
|
386
|
-
|
354
|
+
CallChain.current_id
|
387
355
|
end
|
388
356
|
|
389
357
|
# Obtain the running tasks for this actor
|
@@ -446,16 +414,30 @@ module Celluloid
|
|
446
414
|
end
|
447
415
|
end
|
448
416
|
|
417
|
+
# Timeout on task suspension (eg Sync calls to other actors)
|
418
|
+
def timeout(duration)
|
419
|
+
bt = caller
|
420
|
+
task = Task.current
|
421
|
+
timer = after(duration) do
|
422
|
+
exception = Task::TimeoutError.new
|
423
|
+
exception.set_backtrace bt
|
424
|
+
task.resume exception
|
425
|
+
end
|
426
|
+
yield
|
427
|
+
ensure
|
428
|
+
timer.cancel if timer
|
429
|
+
end
|
430
|
+
|
449
431
|
# Run given block in an exclusive mode: all synchronous calls block the whole
|
450
432
|
# actor, not only current message processing.
|
451
433
|
def exclusive(&block)
|
452
|
-
Thread.current[:
|
434
|
+
Thread.current[:celluloid_task].exclusive(&block)
|
453
435
|
end
|
454
436
|
|
455
437
|
# Are we currently exclusive
|
456
438
|
def exclusive?
|
457
|
-
|
458
|
-
|
439
|
+
task = Thread.current[:celluloid_task]
|
440
|
+
task && task.exclusive?
|
459
441
|
end
|
460
442
|
|
461
443
|
# Call a block after a given interval, returning a Celluloid::Timer object
|
@@ -488,9 +470,8 @@ module Celluloid
|
|
488
470
|
end
|
489
471
|
end
|
490
472
|
|
491
|
-
require 'celluloid/version'
|
492
|
-
|
493
473
|
require 'celluloid/calls'
|
474
|
+
require 'celluloid/call_chain'
|
494
475
|
require 'celluloid/condition'
|
495
476
|
require 'celluloid/thread'
|
496
477
|
require 'celluloid/core_ext'
|
@@ -503,6 +484,7 @@ require 'celluloid/logger'
|
|
503
484
|
require 'celluloid/mailbox'
|
504
485
|
require 'celluloid/evented_mailbox'
|
505
486
|
require 'celluloid/method'
|
487
|
+
require 'celluloid/properties'
|
506
488
|
require 'celluloid/receivers'
|
507
489
|
require 'celluloid/registry'
|
508
490
|
require 'celluloid/responses'
|
@@ -510,6 +492,7 @@ require 'celluloid/signals'
|
|
510
492
|
require 'celluloid/stack_dump'
|
511
493
|
require 'celluloid/system_events'
|
512
494
|
require 'celluloid/tasks'
|
495
|
+
require 'celluloid/task_set'
|
513
496
|
require 'celluloid/thread_handle'
|
514
497
|
require 'celluloid/uuid'
|
515
498
|
|
@@ -535,3 +518,4 @@ Celluloid.task_class = Celluloid::TaskFiber
|
|
535
518
|
Celluloid.logger = Logger.new(STDERR)
|
536
519
|
Celluloid.shutdown_timeout = 10
|
537
520
|
Celluloid.register_shutdown
|
521
|
+
Celluloid.init
|
data/lib/celluloid/actor.rb
CHANGED
@@ -2,16 +2,16 @@ require 'timers'
|
|
2
2
|
|
3
3
|
module Celluloid
|
4
4
|
# Don't do Actor-like things outside Actor scope
|
5
|
-
class NotActorError <
|
5
|
+
class NotActorError < Celluloid::Error; end
|
6
6
|
|
7
7
|
# Trying to do something to a dead actor
|
8
|
-
class DeadActorError <
|
8
|
+
class DeadActorError < Celluloid::Error; end
|
9
9
|
|
10
10
|
# A timeout occured before the given request could complete
|
11
|
-
class TimeoutError <
|
11
|
+
class TimeoutError < Celluloid::Error; end
|
12
12
|
|
13
13
|
# The sender made an error, not the current actor
|
14
|
-
class AbortError <
|
14
|
+
class AbortError < Celluloid::Error
|
15
15
|
attr_reader :cause
|
16
16
|
|
17
17
|
def initialize(cause)
|
@@ -77,8 +77,8 @@ module Celluloid
|
|
77
77
|
# Obtain all running actors in the system
|
78
78
|
def all
|
79
79
|
actors = []
|
80
|
-
|
81
|
-
next unless t.
|
80
|
+
Celluloid.internal_pool.each do |t|
|
81
|
+
next unless t.role == :actor
|
82
82
|
actors << t.actor.proxy if t.actor && t.actor.respond_to?(:proxy)
|
83
83
|
end
|
84
84
|
actors
|
@@ -121,10 +121,7 @@ module Celluloid
|
|
121
121
|
# Forcibly kill a given actor
|
122
122
|
def kill(actor)
|
123
123
|
actor.thread.kill
|
124
|
-
|
125
|
-
actor.mailbox.shutdown
|
126
|
-
rescue DeadActorError
|
127
|
-
end
|
124
|
+
actor.mailbox.shutdown if actor.mailbox.alive?
|
128
125
|
end
|
129
126
|
|
130
127
|
# Wait for an actor to terminate
|
@@ -136,12 +133,15 @@ module Celluloid
|
|
136
133
|
|
137
134
|
# Wrap the given subject with an Actor
|
138
135
|
def initialize(subject, options = {})
|
139
|
-
@subject
|
140
|
-
|
136
|
+
@subject = subject
|
137
|
+
|
138
|
+
@mailbox = options.fetch(:mailbox_class, Mailbox).new
|
139
|
+
@mailbox.max_size = options.fetch(:mailbox_size, nil)
|
140
|
+
|
141
|
+
@task_class = options[:task_class] || Celluloid.task_class
|
141
142
|
@exit_handler = options[:exit_handler]
|
142
143
|
@exclusives = options[:exclusive_methods]
|
143
144
|
@receiver_block_executions = options[:receiver_block_executions]
|
144
|
-
@task_class = options[:task_class] || Celluloid.task_class
|
145
145
|
|
146
146
|
@tasks = TaskSet.new
|
147
147
|
@links = Links.new
|
@@ -193,28 +193,9 @@ module Celluloid
|
|
193
193
|
@running = false
|
194
194
|
end
|
195
195
|
|
196
|
-
# Is this actor running in exclusive mode?
|
197
|
-
def exclusive?
|
198
|
-
@exclusive
|
199
|
-
end
|
200
|
-
|
201
|
-
# Execute a code block in exclusive mode.
|
202
|
-
def exclusive
|
203
|
-
if @exclusive
|
204
|
-
yield
|
205
|
-
else
|
206
|
-
begin
|
207
|
-
@exclusive = true
|
208
|
-
yield
|
209
|
-
ensure
|
210
|
-
@exclusive = false
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
196
|
# Perform a linking request with another actor
|
216
197
|
def linking_request(receiver, type)
|
217
|
-
exclusive do
|
198
|
+
Celluloid.exclusive do
|
218
199
|
start_time = Time.now
|
219
200
|
receiver.mailbox << LinkingRequest.new(Actor.current, type)
|
220
201
|
system_events = []
|
@@ -245,7 +226,7 @@ module Celluloid
|
|
245
226
|
|
246
227
|
# Send a signal with the given name to all waiting methods
|
247
228
|
def signal(name, value = nil)
|
248
|
-
@signals.
|
229
|
+
@signals.broadcast name, value
|
249
230
|
end
|
250
231
|
|
251
232
|
# Wait for the given signal
|
@@ -314,15 +295,17 @@ module Celluloid
|
|
314
295
|
when SystemEvent
|
315
296
|
handle_system_event message
|
316
297
|
when Call
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
end
|
298
|
+
meth = message.method
|
299
|
+
if meth == :__send__
|
300
|
+
meth = message.arguments.first
|
301
|
+
end
|
302
|
+
if @receiver_block_executions && meth
|
303
|
+
if @receiver_block_executions.include?(meth.to_sym)
|
304
|
+
message.execute_block_on_receiver
|
325
305
|
end
|
306
|
+
end
|
307
|
+
|
308
|
+
task(:call, :method_name => meth, :dangerous_suspend => meth == :initialize) {
|
326
309
|
message.dispatch(@subject)
|
327
310
|
}
|
328
311
|
when BlockCall
|
@@ -330,7 +313,9 @@ module Celluloid
|
|
330
313
|
when BlockResponse, Response
|
331
314
|
message.dispatch
|
332
315
|
else
|
333
|
-
@receivers.handle_message(message)
|
316
|
+
unless @receivers.handle_message(message)
|
317
|
+
Logger.debug "Discarded message (unhandled): #{message}"
|
318
|
+
end
|
334
319
|
end
|
335
320
|
message
|
336
321
|
end
|
@@ -339,13 +324,13 @@ module Celluloid
|
|
339
324
|
def handle_system_event(event)
|
340
325
|
case event
|
341
326
|
when ExitEvent
|
342
|
-
task(:exit_handler, @exit_handler) { handle_exit_event event }
|
327
|
+
task(:exit_handler, :method_name => @exit_handler) { handle_exit_event event }
|
343
328
|
when LinkingRequest
|
344
329
|
event.process(links)
|
345
330
|
when NamingRequest
|
346
331
|
@name = event.name
|
347
332
|
when TerminationRequest
|
348
|
-
|
333
|
+
terminate
|
349
334
|
when SignalConditionRequest
|
350
335
|
event.call
|
351
336
|
end
|
@@ -382,17 +367,9 @@ module Celluloid
|
|
382
367
|
|
383
368
|
# Run the user-defined finalizer, if one is set
|
384
369
|
def run_finalizer
|
385
|
-
# FIXME: remove before Celluloid 1.0
|
386
|
-
if @subject.respond_to?(:finalize) && @subject.class.finalizer != :finalize
|
387
|
-
Logger.warn("DEPRECATION WARNING: #{@subject.class}#finalize is deprecated and will be removed in Celluloid 1.0. " +
|
388
|
-
"Define finalizers with '#{@subject.class}.finalizer :callback.'")
|
389
|
-
|
390
|
-
task(:finalizer, :finalize) { @subject.finalize }
|
391
|
-
end
|
392
|
-
|
393
370
|
finalizer = @subject.class.finalizer
|
394
371
|
if finalizer && @subject.respond_to?(finalizer, true)
|
395
|
-
task(:finalizer, :
|
372
|
+
task(:finalizer, :method_name => finalizer, :dangerous_suspend => true) { @subject.__send__(finalizer) }
|
396
373
|
end
|
397
374
|
rescue => ex
|
398
375
|
Logger.crash("#{@subject.class}#finalize crashed!", ex)
|
@@ -402,25 +379,26 @@ module Celluloid
|
|
402
379
|
def cleanup(exit_event)
|
403
380
|
@mailbox.shutdown
|
404
381
|
@links.each do |actor|
|
405
|
-
|
382
|
+
if actor.mailbox.alive?
|
406
383
|
actor.mailbox << exit_event
|
407
|
-
rescue MailboxError
|
408
|
-
# We're exiting/crashing, they're dead. Give up :(
|
409
384
|
end
|
410
385
|
end
|
411
386
|
|
412
|
-
tasks.each { |task| task.terminate }
|
387
|
+
tasks.to_a.each { |task| task.terminate }
|
413
388
|
rescue => ex
|
414
389
|
Logger.crash("#{@subject.class}: CLEANUP CRASHED!", ex)
|
415
390
|
end
|
416
391
|
|
417
392
|
# Run a method inside a task unless it's exclusive
|
418
|
-
def task(task_type,
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
393
|
+
def task(task_type, meta = nil)
|
394
|
+
method_name = meta && meta.fetch(:method_name, nil)
|
395
|
+
@task_class.new(task_type, meta) {
|
396
|
+
if @exclusives && (@exclusives == :all || (method_name && @exclusives.include?(method_name.to_sym)))
|
397
|
+
Celluloid.exclusive { yield }
|
398
|
+
else
|
399
|
+
yield
|
400
|
+
end
|
401
|
+
}.resume
|
424
402
|
end
|
425
403
|
end
|
426
404
|
end
|