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.
- 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
|
[![Build Status](https://secure.travis-ci.org/celluloid/celluloid.png?branch=master)](http://travis-ci.org/celluloid/celluloid)
|
4
4
|
[![Dependency Status](https://gemnasium.com/celluloid/celluloid.png)](https://gemnasium.com/celluloid/celluloid)
|
5
|
-
[![Code Climate](https://codeclimate.com/
|
5
|
+
[![Code Climate](https://codeclimate.com/github/celluloid/celluloid.png)](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)
|