celluloid 0.12.4 → 0.13.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.
- data/README.md +3 -3
- data/lib/celluloid.rb +68 -98
- data/lib/celluloid/actor.rb +42 -22
- data/lib/celluloid/boot.rb +13 -0
- data/lib/celluloid/calls.rb +50 -8
- data/lib/celluloid/condition.rb +64 -0
- data/lib/celluloid/core_ext.rb +1 -1
- data/lib/celluloid/cpu_counter.rb +18 -0
- data/lib/celluloid/future.rb +4 -1
- data/lib/celluloid/internal_pool.rb +62 -44
- data/lib/celluloid/legacy.rb +46 -0
- data/lib/celluloid/links.rb +0 -5
- data/lib/celluloid/logger.rb +10 -4
- data/lib/celluloid/mailbox.rb +2 -1
- data/lib/celluloid/method.rb +5 -0
- data/lib/celluloid/pool_manager.rb +8 -7
- data/lib/celluloid/proxies/actor_proxy.rb +5 -8
- data/lib/celluloid/proxies/async_proxy.rb +5 -1
- data/lib/celluloid/responses.rb +8 -6
- data/lib/celluloid/stack_dump.rb +86 -0
- data/lib/celluloid/supervision_group.rb +4 -2
- data/lib/celluloid/system_events.rb +11 -0
- data/lib/celluloid/{task.rb → tasks.rb} +11 -5
- data/lib/celluloid/tasks/task_fiber.rb +11 -7
- data/lib/celluloid/tasks/task_thread.rb +18 -14
- data/lib/celluloid/thread_handle.rb +10 -6
- data/lib/celluloid/version.rb +1 -1
- data/spec/support/actor_examples.rb +118 -112
- data/spec/support/example_actor_class.rb +9 -5
- data/spec/support/task_examples.rb +2 -2
- metadata +15 -12
- data/lib/celluloid/stack_dumper.rb +0 -45
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
=========
|
3
3
|
[](http://travis-ci.org/celluloid/celluloid)
|
4
4
|
[](https://gemnasium.com/celluloid/celluloid)
|
5
|
-
[](https://codeclimate.com/github/celluloid/celluloid)
|
6
6
|
|
7
7
|
> "I thought of objects being like biological cells and/or individual
|
8
8
|
> computers on a network, only able to communicate with messages"
|
@@ -45,7 +45,7 @@ features which make concurrent programming simple, easy, and fun:
|
|
45
45
|
The central idea: have you tried turning it off and on again? Celluloid
|
46
46
|
takes care of rebooting subcomponents of your application when they crash,
|
47
47
|
whether it's a single actor, or large (potentially multi-tiered) groups of
|
48
|
-
actors that are all interdependent. This means rather
|
48
|
+
actors that are all interdependent. This means rather than worrying about
|
49
49
|
rescuing every last exception, you can just sit back, relax, and let parts
|
50
50
|
of your program crash, knowing Celluloid will automatically reboot them in
|
51
51
|
a clean state. Celluloid provides its own implementation of the core
|
@@ -141,5 +141,5 @@ Contributing to Celluloid
|
|
141
141
|
License
|
142
142
|
-------
|
143
143
|
|
144
|
-
Copyright (c)
|
144
|
+
Copyright (c) 2013 Tony Arcieri. Distributed under the MIT License. See
|
145
145
|
LICENSE.txt for further details.
|
data/lib/celluloid.rb
CHANGED
@@ -2,20 +2,20 @@ require 'logger'
|
|
2
2
|
require 'thread'
|
3
3
|
require 'timeout'
|
4
4
|
require 'set'
|
5
|
-
require 'facter'
|
6
5
|
|
7
6
|
module Celluloid
|
8
7
|
extend self # expose all instance methods as singleton methods
|
9
8
|
|
10
9
|
# How long actors have to terminate
|
11
|
-
SHUTDOWN_TIMEOUT =
|
10
|
+
SHUTDOWN_TIMEOUT = 10
|
12
11
|
|
13
12
|
# Warning message added to Celluloid objects accessed outside their actors
|
14
13
|
BARE_OBJECT_WARNING_MESSAGE = "WARNING: BARE CELLULOID OBJECT "
|
15
14
|
|
16
15
|
class << self
|
17
|
-
attr_accessor :
|
18
|
-
attr_accessor :
|
16
|
+
attr_accessor :internal_pool # Internal thread pool
|
17
|
+
attr_accessor :logger # Thread-safe logger class
|
18
|
+
attr_accessor :task_class # Default task type to use
|
19
19
|
|
20
20
|
def included(klass)
|
21
21
|
klass.send :extend, ClassMethods
|
@@ -24,7 +24,7 @@ module Celluloid
|
|
24
24
|
|
25
25
|
# Are we currently inside of an actor?
|
26
26
|
def actor?
|
27
|
-
!!Thread.current[:
|
27
|
+
!!Thread.current[:celluloid_actor]
|
28
28
|
end
|
29
29
|
|
30
30
|
# Generate a Universally Unique Identifier
|
@@ -34,15 +34,14 @@ module Celluloid
|
|
34
34
|
|
35
35
|
# Obtain the number of CPUs in the system
|
36
36
|
def cores
|
37
|
-
|
38
|
-
Integer(core_count)
|
37
|
+
CPUCounter.cores
|
39
38
|
end
|
40
39
|
alias_method :cpus, :cores
|
41
40
|
alias_method :ncpus, :cores
|
42
41
|
|
43
42
|
# Perform a stack dump of all actors to the given output object
|
44
43
|
def stack_dump(output = STDERR)
|
45
|
-
Celluloid::
|
44
|
+
Celluloid::StackDump.new.dump(output)
|
46
45
|
end
|
47
46
|
alias_method :dump, :stack_dump
|
48
47
|
|
@@ -77,19 +76,8 @@ module Celluloid
|
|
77
76
|
|
78
77
|
Logger.debug "Shutdown completed cleanly"
|
79
78
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
# Terminate all actors at exit
|
84
|
-
at_exit do
|
85
|
-
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION >= "1.9"
|
86
|
-
# workaround for MRI bug losing exit status in at_exit block
|
87
|
-
# http://bugs.ruby-lang.org/issues/5218
|
88
|
-
exit_status = $!.status if $!.is_a?(SystemExit)
|
89
|
-
shutdown
|
90
|
-
exit exit_status if exit_status
|
91
|
-
else
|
92
|
-
shutdown
|
79
|
+
rescue Timeout::Error => ex
|
80
|
+
Logger.error("Couldn't cleanly terminate all actors in #{SHUTDOWN_TIMEOUT} seconds!")
|
93
81
|
end
|
94
82
|
end
|
95
83
|
|
@@ -157,22 +145,40 @@ module Celluloid
|
|
157
145
|
end
|
158
146
|
alias_method :trap_exit, :exit_handler
|
159
147
|
|
160
|
-
#
|
161
|
-
def
|
162
|
-
if
|
163
|
-
@
|
164
|
-
|
165
|
-
|
148
|
+
# Define a callback to run when the actor is finalized.
|
149
|
+
def finalizer(callback = nil)
|
150
|
+
if callback
|
151
|
+
@finalizer = callback.to_sym
|
152
|
+
elsif defined?(@finalizer)
|
153
|
+
@finalizer
|
154
|
+
elsif superclass.respond_to? :finalizer
|
155
|
+
superclass.finalizer
|
166
156
|
end
|
167
157
|
end
|
168
158
|
|
169
159
|
# Define the mailbox class for this class
|
170
|
-
def mailbox_class(klass)
|
171
|
-
|
160
|
+
def mailbox_class(klass = nil)
|
161
|
+
if klass
|
162
|
+
@mailbox_class = klass
|
163
|
+
elsif defined?(@mailbox_class)
|
164
|
+
@mailbox_class
|
165
|
+
elsif superclass.respond_to? :mailbox_class
|
166
|
+
superclass.mailbox_class
|
167
|
+
else
|
168
|
+
Celluloid::Mailbox
|
169
|
+
end
|
172
170
|
end
|
173
171
|
|
174
|
-
def proxy_class(klass)
|
175
|
-
|
172
|
+
def proxy_class(klass = nil)
|
173
|
+
if klass
|
174
|
+
@proxy_class = klass
|
175
|
+
elsif defined?(@proxy_class)
|
176
|
+
@proxy_class
|
177
|
+
elsif superclass.respond_to? :proxy_class
|
178
|
+
superclass.proxy_class
|
179
|
+
else
|
180
|
+
Celluloid::ActorProxy
|
181
|
+
end
|
176
182
|
end
|
177
183
|
|
178
184
|
# Define the default task type for this class
|
@@ -198,35 +204,14 @@ module Celluloid
|
|
198
204
|
end
|
199
205
|
end
|
200
206
|
|
201
|
-
# Create a mailbox for this actor
|
202
|
-
def mailbox_factory
|
203
|
-
if defined?(@mailbox_factory)
|
204
|
-
@mailbox_factory.call
|
205
|
-
elsif superclass.respond_to? :mailbox_factory
|
206
|
-
superclass.mailbox_factory
|
207
|
-
else
|
208
|
-
Mailbox.new
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def proxy_factory
|
213
|
-
if defined?(@proxy_factory)
|
214
|
-
@proxy_factory.call
|
215
|
-
elsif superclass.respond_to?(:proxy_factory)
|
216
|
-
superclass.proxy_factory
|
217
|
-
else
|
218
|
-
nil
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
207
|
# Configuration options for Actor#new
|
223
208
|
def actor_options
|
224
209
|
{
|
225
|
-
:mailbox =>
|
226
|
-
:proxy_class =>
|
210
|
+
:mailbox => mailbox_class.new,
|
211
|
+
:proxy_class => proxy_class,
|
212
|
+
:task_class => task_class,
|
227
213
|
:exit_handler => exit_handler,
|
228
|
-
:exclusive_methods => @exclusive_methods
|
229
|
-
:task_class => task_class
|
214
|
+
:exclusive_methods => @exclusive_methods
|
230
215
|
}
|
231
216
|
end
|
232
217
|
|
@@ -256,7 +241,7 @@ module Celluloid
|
|
256
241
|
|
257
242
|
# Are we being invoked in a different thread from our owner?
|
258
243
|
def leaked?
|
259
|
-
@celluloid_owner != Thread.current[:
|
244
|
+
@celluloid_owner != Thread.current[:celluloid_actor]
|
260
245
|
end
|
261
246
|
|
262
247
|
def inspect
|
@@ -265,7 +250,7 @@ module Celluloid
|
|
265
250
|
if leaked?
|
266
251
|
str << Celluloid::BARE_OBJECT_WARNING_MESSAGE
|
267
252
|
else
|
268
|
-
str << "Celluloid::
|
253
|
+
str << "Celluloid::ActorProxy"
|
269
254
|
end
|
270
255
|
|
271
256
|
str << "(#{self.class}:0x#{object_id.to_s(16)})"
|
@@ -278,29 +263,6 @@ module Celluloid
|
|
278
263
|
|
279
264
|
str.sub!(/\s$/, '>')
|
280
265
|
end
|
281
|
-
|
282
|
-
# Process async calls via method_missing
|
283
|
-
def method_missing(meth, *args, &block)
|
284
|
-
# bang methods are async calls
|
285
|
-
if meth.to_s.match(/!$/)
|
286
|
-
unbanged_meth = meth.to_s.sub(/!$/, '')
|
287
|
-
args.unshift unbanged_meth
|
288
|
-
|
289
|
-
call = AsyncCall.new(:__send__, args, block)
|
290
|
-
begin
|
291
|
-
Thread.current[:actor].mailbox << call
|
292
|
-
rescue MailboxError
|
293
|
-
# Silently swallow asynchronous calls to dead actors. There's no way
|
294
|
-
# to reliably generate DeadActorErrors for async calls, so users of
|
295
|
-
# async calls should find other ways to deal with actors dying
|
296
|
-
# during an async call (i.e. linking/supervisors)
|
297
|
-
end
|
298
|
-
|
299
|
-
return
|
300
|
-
end
|
301
|
-
|
302
|
-
super
|
303
|
-
end
|
304
266
|
end
|
305
267
|
|
306
268
|
#
|
@@ -320,17 +282,17 @@ module Celluloid
|
|
320
282
|
|
321
283
|
# Terminate this actor
|
322
284
|
def terminate
|
323
|
-
Thread.current[:
|
285
|
+
Thread.current[:celluloid_actor].terminate
|
324
286
|
end
|
325
287
|
|
326
288
|
# Send a signal with the given name to all waiting methods
|
327
289
|
def signal(name, value = nil)
|
328
|
-
Thread.current[:
|
290
|
+
Thread.current[:celluloid_actor].signal name, value
|
329
291
|
end
|
330
292
|
|
331
293
|
# Wait for the given signal
|
332
294
|
def wait(name)
|
333
|
-
Thread.current[:
|
295
|
+
Thread.current[:celluloid_actor].wait name
|
334
296
|
end
|
335
297
|
|
336
298
|
# Obtain the current_actor
|
@@ -338,6 +300,11 @@ module Celluloid
|
|
338
300
|
Actor.current
|
339
301
|
end
|
340
302
|
|
303
|
+
# Obtain the UUID of the current call chain
|
304
|
+
def call_chain_id
|
305
|
+
Thread.current[:celluloid_chain_id]
|
306
|
+
end
|
307
|
+
|
341
308
|
# Obtain the name of the current actor
|
342
309
|
def name
|
343
310
|
Actor.name
|
@@ -345,12 +312,12 @@ module Celluloid
|
|
345
312
|
|
346
313
|
# Obtain the running tasks for this actor
|
347
314
|
def tasks
|
348
|
-
Thread.current[:
|
315
|
+
Thread.current[:celluloid_actor].tasks.to_a
|
349
316
|
end
|
350
317
|
|
351
318
|
# Obtain the Celluloid::Links for this actor
|
352
319
|
def links
|
353
|
-
Thread.current[:
|
320
|
+
Thread.current[:celluloid_actor].links
|
354
321
|
end
|
355
322
|
|
356
323
|
# Watch for exit events from another actor
|
@@ -385,7 +352,7 @@ module Celluloid
|
|
385
352
|
|
386
353
|
# Receive an asynchronous message via the actor protocol
|
387
354
|
def receive(timeout = nil, &block)
|
388
|
-
actor = Thread.current[:
|
355
|
+
actor = Thread.current[:celluloid_actor]
|
389
356
|
if actor
|
390
357
|
actor.receive(timeout, &block)
|
391
358
|
else
|
@@ -395,7 +362,7 @@ module Celluloid
|
|
395
362
|
|
396
363
|
# Sleep letting the actor continue processing messages
|
397
364
|
def sleep(interval)
|
398
|
-
actor = Thread.current[:
|
365
|
+
actor = Thread.current[:celluloid_actor]
|
399
366
|
if actor
|
400
367
|
actor.sleep(interval)
|
401
368
|
else
|
@@ -406,23 +373,23 @@ module Celluloid
|
|
406
373
|
# Run given block in an exclusive mode: all synchronous calls block the whole
|
407
374
|
# actor, not only current message processing.
|
408
375
|
def exclusive(&block)
|
409
|
-
Thread.current[:
|
376
|
+
Thread.current[:celluloid_actor].exclusive(&block)
|
410
377
|
end
|
411
378
|
|
412
379
|
# Are we currently exclusive
|
413
380
|
def exclusive?
|
414
|
-
actor = Thread.current[:
|
381
|
+
actor = Thread.current[:celluloid_actor]
|
415
382
|
actor && actor.exclusive?
|
416
383
|
end
|
417
384
|
|
418
385
|
# Call a block after a given interval, returning a Celluloid::Timer object
|
419
386
|
def after(interval, &block)
|
420
|
-
Thread.current[:
|
387
|
+
Thread.current[:celluloid_actor].after(interval, &block)
|
421
388
|
end
|
422
389
|
|
423
390
|
# Call a block every given interval, returning a Celluloid::Timer object
|
424
391
|
def every(interval, &block)
|
425
|
-
Thread.current[:
|
392
|
+
Thread.current[:celluloid_actor].every(interval, &block)
|
426
393
|
end
|
427
394
|
|
428
395
|
# Perform a blocking or computationally intensive action inside an
|
@@ -437,18 +404,18 @@ module Celluloid
|
|
437
404
|
# Handle async calls within an actor itself
|
438
405
|
def async(meth = nil, *args, &block)
|
439
406
|
if meth
|
440
|
-
Actor.async Thread.current[:
|
407
|
+
Actor.async Thread.current[:celluloid_actor].mailbox, meth, *args, &block
|
441
408
|
else
|
442
|
-
Thread.current[:
|
409
|
+
Thread.current[:celluloid_actor].proxy.async
|
443
410
|
end
|
444
411
|
end
|
445
412
|
|
446
413
|
# Handle calls to future within an actor itself
|
447
414
|
def future(meth = nil, *args, &block)
|
448
415
|
if meth
|
449
|
-
Actor.future Thread.current[:
|
416
|
+
Actor.future Thread.current[:celluloid_actor].mailbox, meth, *args, &block
|
450
417
|
else
|
451
|
-
Thread.current[:
|
418
|
+
Thread.current[:celluloid_actor].proxy.future
|
452
419
|
end
|
453
420
|
end
|
454
421
|
end
|
@@ -456,7 +423,9 @@ end
|
|
456
423
|
require 'celluloid/version'
|
457
424
|
|
458
425
|
require 'celluloid/calls'
|
426
|
+
require 'celluloid/condition'
|
459
427
|
require 'celluloid/core_ext'
|
428
|
+
require 'celluloid/cpu_counter'
|
460
429
|
require 'celluloid/fiber'
|
461
430
|
require 'celluloid/fsm'
|
462
431
|
require 'celluloid/internal_pool'
|
@@ -468,9 +437,9 @@ require 'celluloid/receivers'
|
|
468
437
|
require 'celluloid/registry'
|
469
438
|
require 'celluloid/responses'
|
470
439
|
require 'celluloid/signals'
|
471
|
-
require 'celluloid/
|
440
|
+
require 'celluloid/stack_dump'
|
472
441
|
require 'celluloid/system_events'
|
473
|
-
require 'celluloid/
|
442
|
+
require 'celluloid/tasks'
|
474
443
|
require 'celluloid/thread_handle'
|
475
444
|
require 'celluloid/uuid'
|
476
445
|
|
@@ -487,4 +456,5 @@ require 'celluloid/supervisor'
|
|
487
456
|
require 'celluloid/notifications'
|
488
457
|
require 'celluloid/logging'
|
489
458
|
|
459
|
+
require 'celluloid/legacy' unless defined?(CELLULOID_FUTURE)
|
490
460
|
require 'celluloid/boot'
|
data/lib/celluloid/actor.rb
CHANGED
@@ -44,14 +44,14 @@ module Celluloid
|
|
44
44
|
|
45
45
|
# Obtain the current actor
|
46
46
|
def current
|
47
|
-
actor = Thread.current[:
|
47
|
+
actor = Thread.current[:celluloid_actor]
|
48
48
|
raise NotActorError, "not in actor scope" unless actor
|
49
49
|
actor.proxy
|
50
50
|
end
|
51
51
|
|
52
52
|
# Obtain the name of the current actor
|
53
53
|
def name
|
54
|
-
actor = Thread.current[:
|
54
|
+
actor = Thread.current[:celluloid_actor]
|
55
55
|
raise NotActorError, "not in actor scope" unless actor
|
56
56
|
actor.name
|
57
57
|
end
|
@@ -66,7 +66,7 @@ module Celluloid
|
|
66
66
|
raise DeadActorError, "attempted to call a dead actor"
|
67
67
|
end
|
68
68
|
|
69
|
-
if Thread.current[:
|
69
|
+
if Thread.current[:celluloid_task] && !Celluloid.exclusive?
|
70
70
|
Task.suspend(:callwait).value
|
71
71
|
else
|
72
72
|
response = loop do
|
@@ -74,7 +74,7 @@ module Celluloid
|
|
74
74
|
msg.respond_to?(:call) and msg.call == call
|
75
75
|
end
|
76
76
|
break message unless message.is_a?(SystemEvent)
|
77
|
-
Thread.current[:
|
77
|
+
Thread.current[:celluloid_actor].handle_system_event(message)
|
78
78
|
end
|
79
79
|
|
80
80
|
response.value
|
@@ -104,7 +104,7 @@ module Celluloid
|
|
104
104
|
def all
|
105
105
|
actors = []
|
106
106
|
Thread.list.each do |t|
|
107
|
-
actor = t[:
|
107
|
+
actor = t[:celluloid_actor]
|
108
108
|
actors << actor.proxy if actor and actor.respond_to?(:proxy)
|
109
109
|
end
|
110
110
|
actors
|
@@ -113,25 +113,25 @@ module Celluloid
|
|
113
113
|
# Watch for exit events from another actor
|
114
114
|
def monitor(actor)
|
115
115
|
raise NotActorError, "can't link outside actor context" unless Celluloid.actor?
|
116
|
-
Thread.current[:
|
116
|
+
Thread.current[:celluloid_actor].linking_request(actor, :link)
|
117
117
|
end
|
118
118
|
|
119
119
|
# Stop waiting for exit events from another actor
|
120
120
|
def unmonitor(actor)
|
121
121
|
raise NotActorError, "can't link outside actor context" unless Celluloid.actor?
|
122
|
-
Thread.current[:
|
122
|
+
Thread.current[:celluloid_actor].linking_request(actor, :unlink)
|
123
123
|
end
|
124
124
|
|
125
125
|
# Link to another actor
|
126
126
|
def link(actor)
|
127
127
|
monitor actor
|
128
|
-
Thread.current[:
|
128
|
+
Thread.current[:celluloid_actor].links << actor
|
129
129
|
end
|
130
130
|
|
131
131
|
# Unlink from another actor
|
132
132
|
def unlink(actor)
|
133
133
|
unmonitor actor
|
134
|
-
Thread.current[:
|
134
|
+
Thread.current[:celluloid_actor].links.delete actor
|
135
135
|
end
|
136
136
|
|
137
137
|
# Are we monitoring the given actor?
|
@@ -141,7 +141,7 @@ module Celluloid
|
|
141
141
|
|
142
142
|
# Are we bidirectionally linked to the given actor?
|
143
143
|
def linked_to?(actor)
|
144
|
-
monitoring?(actor) && Thread.current[:
|
144
|
+
monitoring?(actor) && Thread.current[:celluloid_actor].links.include?(actor)
|
145
145
|
end
|
146
146
|
|
147
147
|
# Forcibly kill a given actor
|
@@ -164,7 +164,6 @@ module Celluloid
|
|
164
164
|
def initialize(subject, options = {})
|
165
165
|
@subject = subject
|
166
166
|
@mailbox = options[:mailbox] || Mailbox.new
|
167
|
-
@proxy_class = options[:proxy_class] || ActorProxy
|
168
167
|
@exit_handler = options[:exit_handler]
|
169
168
|
@exclusives = options[:exclusive_methods]
|
170
169
|
@task_class = options[:task_class] || Celluloid.task_class
|
@@ -179,12 +178,12 @@ module Celluloid
|
|
179
178
|
@name = nil
|
180
179
|
|
181
180
|
@thread = ThreadHandle.new do
|
182
|
-
Thread.current[:
|
183
|
-
Thread.current[:
|
181
|
+
Thread.current[:celluloid_actor] = self
|
182
|
+
Thread.current[:celluloid_mailbox] = @mailbox
|
184
183
|
run
|
185
184
|
end
|
186
185
|
|
187
|
-
@proxy =
|
186
|
+
@proxy = (options[:proxy_class] || ActorProxy).new(self)
|
188
187
|
@subject.instance_variable_set(OWNER_IVAR, self)
|
189
188
|
end
|
190
189
|
|
@@ -238,13 +237,15 @@ module Celluloid
|
|
238
237
|
def linking_request(receiver, type)
|
239
238
|
exclusive do
|
240
239
|
start_time = Time.now
|
241
|
-
|
242
240
|
receiver.mailbox << LinkingRequest.new(Actor.current, type)
|
243
241
|
system_events = []
|
242
|
+
|
244
243
|
loop do
|
245
244
|
wait_interval = start_time + LINKING_TIMEOUT - Time.now
|
246
245
|
message = @mailbox.receive(wait_interval) do |msg|
|
247
|
-
msg.is_a?(LinkingResponse) &&
|
246
|
+
msg.is_a?(LinkingResponse) &&
|
247
|
+
msg.actor.mailbox.address == receiver.mailbox.address &&
|
248
|
+
msg.type == type
|
248
249
|
end
|
249
250
|
|
250
251
|
case message
|
@@ -309,7 +310,7 @@ module Celluloid
|
|
309
310
|
|
310
311
|
# Sleep for the given amount of time
|
311
312
|
def sleep(interval)
|
312
|
-
task = Thread.current[:
|
313
|
+
task = Thread.current[:celluloid_task]
|
313
314
|
if task && !Celluloid.exclusive?
|
314
315
|
@timers.after(interval) { task.resume }
|
315
316
|
Task.suspend :sleeping
|
@@ -344,6 +345,8 @@ module Celluloid
|
|
344
345
|
@name = event.name
|
345
346
|
when TerminationRequest
|
346
347
|
@running = false
|
348
|
+
when SignalConditionRequest
|
349
|
+
event.call
|
347
350
|
end
|
348
351
|
end
|
349
352
|
|
@@ -372,14 +375,24 @@ module Celluloid
|
|
372
375
|
run_finalizer
|
373
376
|
cleanup exit_event
|
374
377
|
ensure
|
375
|
-
Thread.current[:
|
376
|
-
Thread.current[:
|
378
|
+
Thread.current[:celluloid_actor] = nil
|
379
|
+
Thread.current[:celluloid_mailbox] = nil
|
377
380
|
end
|
378
381
|
|
379
382
|
# Run the user-defined finalizer, if one is set
|
380
383
|
def run_finalizer
|
381
|
-
|
382
|
-
|
384
|
+
# FIXME: remove before Celluloid 1.0
|
385
|
+
if @subject.respond_to?(:finalize) && @subject.class.finalizer != :finalize
|
386
|
+
Logger.warn("DEPRECATION WARNING: #{@subject.class}#finalize is deprecated and will be removed in Celluloid 1.0. " +
|
387
|
+
"Define finalizers with '#{@subject.class}.finalizer :callback.'")
|
388
|
+
|
389
|
+
task(:finalizer, :finalize) { @subject.finalize }
|
390
|
+
end
|
391
|
+
|
392
|
+
finalizer = @subject.class.finalizer
|
393
|
+
if finalizer && @subject.respond_to?(finalizer)
|
394
|
+
task(:finalizer, :finalize) { @subject.__send__(finalizer) }
|
395
|
+
end
|
383
396
|
rescue => ex
|
384
397
|
Logger.crash("#{@subject.class}#finalize crashed!", ex)
|
385
398
|
end
|
@@ -387,7 +400,14 @@ module Celluloid
|
|
387
400
|
# Clean up after this actor
|
388
401
|
def cleanup(exit_event)
|
389
402
|
@mailbox.shutdown
|
390
|
-
@links.
|
403
|
+
@links.each do |actor|
|
404
|
+
begin
|
405
|
+
actor.mailbox << exit_event
|
406
|
+
rescue MailboxError
|
407
|
+
# We're exiting/crashing, they're dead. Give up :(
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
391
411
|
tasks.each { |task| task.terminate }
|
392
412
|
rescue => ex
|
393
413
|
Logger.crash("#{@subject.class}: CLEANUP CRASHED!", ex)
|