celluloid 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +34 -3
- data/lib/celluloid.rb +38 -29
- data/lib/celluloid/actor.rb +14 -26
- data/lib/celluloid/actor_proxy.rb +4 -0
- data/lib/celluloid/calls.rb +1 -1
- data/lib/celluloid/core_ext.rb +3 -9
- data/lib/celluloid/{fibers_are_hard.rb → fiber.rb} +31 -1
- data/lib/celluloid/io/reactor.rb +1 -1
- data/lib/celluloid/links.rb +61 -0
- data/lib/celluloid/mailbox.rb +3 -0
- data/lib/celluloid/receivers.rb +1 -1
- data/lib/celluloid/signals.rb +2 -4
- data/lib/celluloid/supervisor.rb +7 -2
- data/lib/celluloid/version.rb +1 -1
- metadata +25 -26
- data/lib/celluloid/linking.rb +0 -89
data/README.md
CHANGED
@@ -329,6 +329,35 @@ working, freshly-restarted version.
|
|
329
329
|
The main use of the registry is for interfacing with actors that are
|
330
330
|
automatically restarted by supervisors when they crash.
|
331
331
|
|
332
|
+
Applications
|
333
|
+
------------
|
334
|
+
|
335
|
+
Celluloid provides a DSL for describing all of the actors in a given
|
336
|
+
application. This lets you start a group of actors in one swoop and
|
337
|
+
also provides an additional level of supervision: applications supervise
|
338
|
+
the supervisors of all the actors in your system, an approach known
|
339
|
+
as supervision trees.
|
340
|
+
|
341
|
+
Define Celluloid::Applications with the following syntax:
|
342
|
+
|
343
|
+
class MyApplication < Celluloid::Application
|
344
|
+
supervise MyActor, :as => :my_actor
|
345
|
+
supervise AnotherActor, :as => :another_actor
|
346
|
+
end
|
347
|
+
|
348
|
+
This will start the MyActor and AnotherActor actors under a supervisor and
|
349
|
+
automatically register them as Celluloid::Actor[:my_actor] and
|
350
|
+
Celluloid::Actor[:another_actor].
|
351
|
+
|
352
|
+
To launch your application, do:
|
353
|
+
|
354
|
+
MyApplication.run
|
355
|
+
|
356
|
+
This launches your application in the foreground. To launch in in the
|
357
|
+
background, do:
|
358
|
+
|
359
|
+
MyApplication.run!
|
360
|
+
|
332
361
|
Signaling
|
333
362
|
---------
|
334
363
|
|
@@ -458,9 +487,11 @@ Here are a few rules you can follow to keep this from happening:
|
|
458
487
|
|
459
488
|
1. ***NEVER RETURN SELF*** (or pass self as an argument to other actors): in
|
460
489
|
cases where you want to pass an actor around to other actors or threads,
|
461
|
-
use Celluloid.current_actor
|
462
|
-
|
463
|
-
|
490
|
+
use Celluloid.current_actor, or if you're within an actor itself, you can
|
491
|
+
just call the #current_actor method. If you really need to get ahold of
|
492
|
+
"self" in order to add instance-specific behavior, e.g for metaprogramming
|
493
|
+
purposes or adding stubs during tests, call MyActor#wrapped_object to
|
494
|
+
obtain the actual object an actor is wrapping.
|
464
495
|
|
465
496
|
2. Don't mutate the state of objects you've sent in calls to other actors:
|
466
497
|
This means you must think about data in one of two different ways: either
|
data/lib/celluloid.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'logger'
|
2
2
|
require 'thread'
|
3
|
-
require 'celluloid/fibers_are_hard'
|
4
3
|
|
5
4
|
module Celluloid
|
6
5
|
@logger = Logger.new STDERR
|
@@ -9,8 +8,7 @@ module Celluloid
|
|
9
8
|
attr_accessor :logger # Thread-safe logger class
|
10
9
|
|
11
10
|
def included(klass)
|
12
|
-
klass.send :extend,
|
13
|
-
klass.send :include, Linking
|
11
|
+
klass.send :extend, ClassMethods
|
14
12
|
end
|
15
13
|
|
16
14
|
# Are we currently inside of an actor?
|
@@ -20,10 +18,10 @@ module Celluloid
|
|
20
18
|
|
21
19
|
# Obtain the currently running actor (if one exists)
|
22
20
|
def current_actor
|
23
|
-
actor = Thread.current[:
|
21
|
+
actor = Thread.current[:actor]
|
24
22
|
raise NotActorError, "not in actor scope" unless actor
|
25
23
|
|
26
|
-
actor
|
24
|
+
actor.proxy
|
27
25
|
end
|
28
26
|
|
29
27
|
# Receive an asynchronous message
|
@@ -32,33 +30,13 @@ module Celluloid
|
|
32
30
|
if actor
|
33
31
|
actor.receive(&block)
|
34
32
|
else
|
35
|
-
Thread.
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Create a fiber that participates in the Celluloid protocol
|
40
|
-
def fiber(*args)
|
41
|
-
actor = Thread.current[:actor]
|
42
|
-
proxy = Thread.current[:actor_proxy]
|
43
|
-
mailbox = Thread.current[:mailbox]
|
44
|
-
|
45
|
-
Fiber.new do
|
46
|
-
Thread.current[:actor] = actor
|
47
|
-
Thread.current[:actor_proxy] = proxy
|
48
|
-
Thread.current[:mailbox] = mailbox
|
49
|
-
|
50
|
-
yield(*args)
|
33
|
+
Thread.mailbox.receive(&block)
|
51
34
|
end
|
52
35
|
end
|
53
36
|
|
54
37
|
# Resume a fiber that participates in the Celluloid protocol
|
55
38
|
def resume_fiber(fiber, value = nil)
|
56
|
-
|
57
|
-
if actor
|
58
|
-
actor.run_fiber fiber, value
|
59
|
-
else
|
60
|
-
fiber.resume value
|
61
|
-
end
|
39
|
+
fiber.resume value
|
62
40
|
end
|
63
41
|
end
|
64
42
|
|
@@ -74,7 +52,7 @@ module Celluloid
|
|
74
52
|
|
75
53
|
# Create a new actor and link to the current one
|
76
54
|
def new_link(*args, &block)
|
77
|
-
current_actor =
|
55
|
+
current_actor = Celluloid.current_actor
|
78
56
|
raise NotActorError, "can't link outside actor context" unless current_actor
|
79
57
|
|
80
58
|
proxy = Celluloid::Actor.new(allocate).proxy
|
@@ -165,6 +143,36 @@ module Celluloid
|
|
165
143
|
# be shared with at least the actor thread. Tread carefully.
|
166
144
|
def wrapped_object; self; end
|
167
145
|
|
146
|
+
# Obtain the Celluloid::Links for this actor
|
147
|
+
def links
|
148
|
+
Thread.current[:actor].links
|
149
|
+
end
|
150
|
+
|
151
|
+
# Link this actor to another, allowing it to crash or react to errors
|
152
|
+
def link(actor)
|
153
|
+
actor.notify_link current_actor
|
154
|
+
notify_link actor
|
155
|
+
end
|
156
|
+
|
157
|
+
# Remove links to another actor
|
158
|
+
def unlink(actor)
|
159
|
+
actor.notify_unlink current_actor
|
160
|
+
notify_unlink actor
|
161
|
+
end
|
162
|
+
|
163
|
+
def notify_link(actor)
|
164
|
+
links << actor
|
165
|
+
end
|
166
|
+
|
167
|
+
def notify_unlink(actor)
|
168
|
+
links.delete actor
|
169
|
+
end
|
170
|
+
|
171
|
+
# Is this actor linked to another?
|
172
|
+
def linked_to?(actor)
|
173
|
+
Thread.current[:actor].links.include? actor
|
174
|
+
end
|
175
|
+
|
168
176
|
# Receive an asynchronous message via the actor protocol
|
169
177
|
def receive(&block)
|
170
178
|
Celluloid.receive(&block)
|
@@ -207,7 +215,8 @@ require 'celluloid/actor_proxy'
|
|
207
215
|
require 'celluloid/calls'
|
208
216
|
require 'celluloid/core_ext'
|
209
217
|
require 'celluloid/events'
|
210
|
-
require 'celluloid/
|
218
|
+
require 'celluloid/fiber'
|
219
|
+
require 'celluloid/links'
|
211
220
|
require 'celluloid/mailbox'
|
212
221
|
require 'celluloid/receivers'
|
213
222
|
require 'celluloid/registry'
|
data/lib/celluloid/actor.rb
CHANGED
@@ -20,7 +20,6 @@ module Celluloid
|
|
20
20
|
# messages.
|
21
21
|
class Actor
|
22
22
|
extend Registry
|
23
|
-
include Linking
|
24
23
|
|
25
24
|
attr_reader :proxy
|
26
25
|
attr_reader :links
|
@@ -28,8 +27,7 @@ module Celluloid
|
|
28
27
|
|
29
28
|
# Invoke a method on the given actor via its mailbox
|
30
29
|
def self.call(mailbox, meth, *args, &block)
|
31
|
-
|
32
|
-
call = SyncCall.new(our_mailbox, meth, args, block)
|
30
|
+
call = SyncCall.new(Thread.mailbox, meth, args, block)
|
33
31
|
|
34
32
|
begin
|
35
33
|
mailbox << call
|
@@ -42,8 +40,8 @@ module Celluloid
|
|
42
40
|
response = Fiber.yield(call)
|
43
41
|
else
|
44
42
|
# Otherwise we're inside a normal thread, so block
|
45
|
-
response =
|
46
|
-
msg.
|
43
|
+
response = Thread.mailbox.receive do |msg|
|
44
|
+
msg.respond_to?(:call_id) and msg.call_id == call.id
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -52,9 +50,8 @@ module Celluloid
|
|
52
50
|
|
53
51
|
# Invoke a method asynchronously on an actor via its mailbox
|
54
52
|
def self.async(mailbox, meth, *args, &block)
|
55
|
-
our_mailbox = Thread.current.mailbox
|
56
53
|
begin
|
57
|
-
mailbox << AsyncCall.new(
|
54
|
+
mailbox << AsyncCall.new(Thread.mailbox, meth, args, block)
|
58
55
|
rescue MailboxError
|
59
56
|
# Silently swallow asynchronous calls to dead actors. There's no way
|
60
57
|
# to reliably generate DeadActorErrors for async calls, so users of
|
@@ -76,14 +73,13 @@ module Celluloid
|
|
76
73
|
@links = Links.new
|
77
74
|
@signals = Signals.new
|
78
75
|
@receivers = Receivers.new
|
79
|
-
@proxy = ActorProxy.new(@mailbox)
|
76
|
+
@proxy = ActorProxy.new(@mailbox, self.class.to_s)
|
80
77
|
@running = true
|
81
78
|
@pending_calls = {}
|
82
79
|
|
83
80
|
@thread = Pool.get do
|
84
|
-
Thread.current[:actor]
|
85
|
-
Thread.current[:
|
86
|
-
Thread.current[:mailbox] = @mailbox
|
81
|
+
Thread.current[:actor] = self
|
82
|
+
Thread.current[:mailbox] = @mailbox
|
87
83
|
|
88
84
|
run
|
89
85
|
end
|
@@ -121,8 +117,7 @@ module Celluloid
|
|
121
117
|
begin
|
122
118
|
message = @mailbox.receive
|
123
119
|
rescue ExitEvent => exit_event
|
124
|
-
|
125
|
-
run_fiber fiber
|
120
|
+
Celluloid::Fiber.new { handle_exit_event exit_event; nil }.resume
|
126
121
|
retry
|
127
122
|
end
|
128
123
|
|
@@ -140,29 +135,22 @@ module Celluloid
|
|
140
135
|
Pool.put @thread
|
141
136
|
end
|
142
137
|
|
143
|
-
#
|
144
|
-
def
|
145
|
-
|
146
|
-
|
147
|
-
@pending_calls[result.id] = fiber if fiber.alive?
|
148
|
-
elsif result
|
149
|
-
warning = "non-call returned from fiber: #{result.class}"
|
150
|
-
Celluloid.logger.debug warning if Celluloid.logger
|
151
|
-
end
|
152
|
-
nil
|
138
|
+
# Register a fiber waiting for the response to a Celluloid::Call
|
139
|
+
def register_fiber(call, fiber)
|
140
|
+
raise ArgumentError, "attempted to register a dead fiber" unless fiber.alive?
|
141
|
+
@pending_calls[call.id] = fiber
|
153
142
|
end
|
154
143
|
|
155
144
|
# Handle an incoming message
|
156
145
|
def handle_message(message)
|
157
146
|
case message
|
158
147
|
when Call
|
159
|
-
|
160
|
-
run_fiber fiber
|
148
|
+
Celluloid::Fiber.new { message.dispatch(@subject); nil }.resume
|
161
149
|
when Response
|
162
150
|
fiber = @pending_calls.delete(message.call_id)
|
163
151
|
|
164
152
|
if fiber
|
165
|
-
|
153
|
+
fiber.resume message
|
166
154
|
else
|
167
155
|
warning = "spurious response to call #{message.call_id}"
|
168
156
|
Celluloid.logger.debug if Celluloid.logger
|
data/lib/celluloid/calls.rb
CHANGED
@@ -87,7 +87,7 @@ module Celluloid
|
|
87
87
|
obj.send(@method, *@arguments, &@block)
|
88
88
|
rescue AbortError => ex
|
89
89
|
# Swallow aborted async calls, as they indicate the caller made a mistake
|
90
|
-
|
90
|
+
log_error ex, "#{obj.class}: async call aborted!"
|
91
91
|
end
|
92
92
|
|
93
93
|
def log_error(ex, message)
|
data/lib/celluloid/core_ext.rb
CHANGED
@@ -1,13 +1,7 @@
|
|
1
1
|
# Monkeypatch Thread to allow lazy access to its Celluloid::Mailbox
|
2
2
|
class Thread
|
3
|
-
# Retrieve the current
|
4
|
-
def mailbox
|
5
|
-
|
6
|
-
if Thread.current != self
|
7
|
-
raise "attempt to access an uninitialized mailbox"
|
8
|
-
end
|
9
|
-
|
10
|
-
self[:mailbox] = Celluloid::Mailbox.new
|
11
|
-
end
|
3
|
+
# Retrieve the mailbox for the current thread or lazily initialize it
|
4
|
+
def self.mailbox
|
5
|
+
current[:mailbox] ||= Celluloid::Mailbox.new
|
12
6
|
end
|
13
7
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Every time I look at this code a little part of me dies...
|
2
2
|
begin
|
3
3
|
require 'fiber'
|
4
4
|
rescue LoadError => ex
|
@@ -31,3 +31,33 @@ rescue LoadError => ex
|
|
31
31
|
raise ex
|
32
32
|
end
|
33
33
|
end
|
34
|
+
|
35
|
+
module Celluloid
|
36
|
+
class Fiber < ::Fiber
|
37
|
+
def initialize(*args)
|
38
|
+
actor = Thread.current[:actor]
|
39
|
+
mailbox = Thread.current[:mailbox]
|
40
|
+
|
41
|
+
super do
|
42
|
+
Thread.current[:actor] = actor
|
43
|
+
Thread.current[:mailbox] = mailbox
|
44
|
+
|
45
|
+
yield(*args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def resume(value = nil)
|
50
|
+
result = super
|
51
|
+
actor = Thread.current[:actor]
|
52
|
+
return result unless actor
|
53
|
+
|
54
|
+
if result.is_a? Celluloid::Call
|
55
|
+
actor.register_fiber result, self
|
56
|
+
elsif result
|
57
|
+
warning = "non-call returned from fiber: #{result.class}"
|
58
|
+
Celluloid.logger.debug warning if Celluloid.logger
|
59
|
+
end
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/celluloid/io/reactor.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Celluloid
|
4
|
+
# Thread safe storage of inter-actor links
|
5
|
+
class Links
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@links = {}
|
10
|
+
@lock = Mutex.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add an actor to the current links
|
14
|
+
def <<(actor)
|
15
|
+
@lock.synchronize do
|
16
|
+
@links[actor.mailbox.address] = actor
|
17
|
+
end
|
18
|
+
actor
|
19
|
+
end
|
20
|
+
|
21
|
+
# Do links include the given actor?
|
22
|
+
def include?(actor)
|
23
|
+
@lock.synchronize do
|
24
|
+
@links.has_key? actor.mailbox.address
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Remove an actor from the links
|
29
|
+
def delete(actor)
|
30
|
+
@lock.synchronize do
|
31
|
+
@links.delete actor.mailbox.address
|
32
|
+
end
|
33
|
+
actor
|
34
|
+
end
|
35
|
+
|
36
|
+
# Iterate through all links
|
37
|
+
def each
|
38
|
+
@lock.synchronize do
|
39
|
+
@links.each { |_, actor| yield(actor) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Map across links
|
44
|
+
def map
|
45
|
+
result = []
|
46
|
+
each { |actor| result << yield(actor) }
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
# Send an event message to all actors
|
51
|
+
def send_event(event)
|
52
|
+
each { |actor| actor.mailbox.system_event event }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Generate a string representation
|
56
|
+
def inspect
|
57
|
+
links = self.map(&:inspect).join(',')
|
58
|
+
"#<#{self.class}[#{links}]>"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/celluloid/mailbox.rb
CHANGED
data/lib/celluloid/receivers.rb
CHANGED
data/lib/celluloid/signals.rb
CHANGED
data/lib/celluloid/supervisor.rb
CHANGED
@@ -26,11 +26,16 @@ module Celluloid
|
|
26
26
|
|
27
27
|
begin
|
28
28
|
@actor = @klass.new_link(*@args, &@block)
|
29
|
-
rescue
|
29
|
+
rescue => ex
|
30
30
|
failures += 1
|
31
31
|
if failures >= start_attempts
|
32
32
|
failures = 0
|
33
|
-
|
33
|
+
|
34
|
+
warning = "#{@klass} is crashing on initialize repeatedly, sleeping for #{sleep_interval} seconds\n"
|
35
|
+
warning << "#{ex.class}: #{ex}\n "
|
36
|
+
warning << "#{ex.backtrace.join("\n ")}"
|
37
|
+
|
38
|
+
Celluloid.logger.warn warning if Celluloid.logger
|
34
39
|
sleep sleep_interval
|
35
40
|
end
|
36
41
|
retry
|
data/lib/celluloid/version.rb
CHANGED
metadata
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: celluloid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
4
|
+
version: 0.6.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tony Arcieri
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11-
|
12
|
+
date: 2011-11-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
|
16
|
+
requirement: &70242345718900 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
17
18
|
requirements:
|
18
19
|
- - ! '>='
|
19
20
|
- !ruby/object:Gem::Version
|
20
21
|
version: '0'
|
21
|
-
none: false
|
22
|
-
requirement: *2056
|
23
|
-
prerelease: false
|
24
22
|
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70242345718900
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
|
27
|
+
requirement: &70242345718300 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
28
29
|
requirements:
|
29
30
|
- - ! '>='
|
30
31
|
- !ruby/object:Gem::Version
|
31
32
|
version: 2.7.0
|
32
|
-
none: false
|
33
|
-
requirement: *2074
|
34
|
-
prerelease: false
|
35
33
|
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70242345718300
|
36
36
|
description: Celluloid is a concurrent object framework inspired by the Actor Model
|
37
37
|
email:
|
38
38
|
- tony@medioh.com
|
@@ -41,7 +41,6 @@ extensions: []
|
|
41
41
|
extra_rdoc_files: []
|
42
42
|
files:
|
43
43
|
- README.md
|
44
|
-
- lib/celluloid.rb
|
45
44
|
- lib/celluloid/actor.rb
|
46
45
|
- lib/celluloid/actor_pool.rb
|
47
46
|
- lib/celluloid/actor_proxy.rb
|
@@ -49,10 +48,13 @@ files:
|
|
49
48
|
- lib/celluloid/calls.rb
|
50
49
|
- lib/celluloid/core_ext.rb
|
51
50
|
- lib/celluloid/events.rb
|
52
|
-
- lib/celluloid/
|
51
|
+
- lib/celluloid/fiber.rb
|
53
52
|
- lib/celluloid/future.rb
|
53
|
+
- lib/celluloid/io/mailbox.rb
|
54
|
+
- lib/celluloid/io/reactor.rb
|
55
|
+
- lib/celluloid/io/waker.rb
|
54
56
|
- lib/celluloid/io.rb
|
55
|
-
- lib/celluloid/
|
57
|
+
- lib/celluloid/links.rb
|
56
58
|
- lib/celluloid/mailbox.rb
|
57
59
|
- lib/celluloid/receivers.rb
|
58
60
|
- lib/celluloid/registry.rb
|
@@ -62,34 +64,31 @@ files:
|
|
62
64
|
- lib/celluloid/supervisor.rb
|
63
65
|
- lib/celluloid/tcp_server.rb
|
64
66
|
- lib/celluloid/version.rb
|
65
|
-
- lib/celluloid
|
66
|
-
- lib/celluloid/io/reactor.rb
|
67
|
-
- lib/celluloid/io/waker.rb
|
67
|
+
- lib/celluloid.rb
|
68
68
|
homepage: https://github.com/tarcieri/celluloid
|
69
69
|
licenses:
|
70
70
|
- MIT
|
71
|
-
post_install_message:
|
71
|
+
post_install_message:
|
72
72
|
rdoc_options: []
|
73
73
|
require_paths:
|
74
74
|
- lib
|
75
75
|
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
76
77
|
requirements:
|
77
78
|
- - ! '>='
|
78
79
|
- !ruby/object:Gem::Version
|
79
80
|
version: '0'
|
80
|
-
none: false
|
81
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
82
83
|
requirements:
|
83
84
|
- - ! '>='
|
84
85
|
- !ruby/object:Gem::Version
|
85
86
|
version: 1.3.6
|
86
|
-
none: false
|
87
87
|
requirements: []
|
88
|
-
rubyforge_project:
|
89
|
-
rubygems_version: 1.8.
|
90
|
-
signing_key:
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.8.10
|
90
|
+
signing_key:
|
91
91
|
specification_version: 3
|
92
92
|
summary: Celluloid is a concurrent object framework inspired by the Actor Model
|
93
93
|
test_files: []
|
94
|
-
has_rdoc:
|
95
|
-
...
|
94
|
+
has_rdoc:
|
data/lib/celluloid/linking.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'thread'
|
3
|
-
|
4
|
-
module Celluloid
|
5
|
-
# Thread safe storage of inter-actor links
|
6
|
-
class Links
|
7
|
-
include Enumerable
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@links = Set.new
|
11
|
-
@lock = Mutex.new
|
12
|
-
end
|
13
|
-
|
14
|
-
# Add an actor to the current links
|
15
|
-
def <<(actor)
|
16
|
-
@lock.synchronize do
|
17
|
-
@links << actor
|
18
|
-
end
|
19
|
-
actor
|
20
|
-
end
|
21
|
-
|
22
|
-
# Do links include the given actor?
|
23
|
-
def include?(actor)
|
24
|
-
@lock.synchronize do
|
25
|
-
@links.include? actor
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Remove an actor from the links
|
30
|
-
def delete(actor)
|
31
|
-
@lock.synchronize do
|
32
|
-
@links.delete actor
|
33
|
-
end
|
34
|
-
actor
|
35
|
-
end
|
36
|
-
|
37
|
-
# Iterate through all links
|
38
|
-
def each(&block)
|
39
|
-
@lock.synchronize do
|
40
|
-
@links.each(&block)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Send an event message to all actors
|
45
|
-
def send_event(event)
|
46
|
-
each { |actor| actor.mailbox.system_event event }
|
47
|
-
end
|
48
|
-
|
49
|
-
# Generate a string representation
|
50
|
-
def inspect
|
51
|
-
@lock.synchronize do
|
52
|
-
links = @links.to_a.map { |l| "#{l.class}:#{l.object_id}" }.join(',')
|
53
|
-
"#<#{self.class}[#{links}]>"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Support for linking actors together so they can crash or react to errors
|
59
|
-
module Linking
|
60
|
-
# Link this actor to another, allowing it to crash or react to errors
|
61
|
-
def link(actor)
|
62
|
-
current_actor = Thread.current[:actor]
|
63
|
-
|
64
|
-
actor.notify_link(current_actor.proxy)
|
65
|
-
current_actor.notify_link(actor)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Remove links to another actor
|
69
|
-
def unlink(actor)
|
70
|
-
current_actor = Thread.current[:actor]
|
71
|
-
|
72
|
-
actor.notify_unlink(current_actor.proxy)
|
73
|
-
current_actor.notify_unlink(actor)
|
74
|
-
end
|
75
|
-
|
76
|
-
def notify_link(actor)
|
77
|
-
Thread.current[:actor].links << actor
|
78
|
-
end
|
79
|
-
|
80
|
-
def notify_unlink(actor)
|
81
|
-
Thread.current[:actor].links.delete actor
|
82
|
-
end
|
83
|
-
|
84
|
-
# Is this actor linked to another?
|
85
|
-
def linked_to?(actor)
|
86
|
-
Thread.current[:actor].links.include? actor
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|