celluloid 0.14.1 → 0.15.0.pre
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.
- 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
|