celluloid 0.18.0.pre → 0.18.0

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.
Files changed (177) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +258 -39
  3. data/CONDUCT.md +13 -0
  4. data/CONTRIBUTING.md +39 -0
  5. data/README.md +54 -165
  6. data/REFACTOR.md +1 -0
  7. data/architecture.md +120 -0
  8. data/examples/basic_usage.rb +1 -1
  9. data/examples/configurations.rb +78 -0
  10. data/examples/futures.rb +1 -1
  11. data/examples/ring.rb +5 -4
  12. data/examples/simple_pmap.rb +1 -1
  13. data/examples/stack.rb +2 -2
  14. data/examples/supervisors_and_registry.rb +82 -0
  15. data/examples/timers.rb +2 -2
  16. data/lib/celluloid.rb +72 -47
  17. data/lib/celluloid/actor.rb +27 -17
  18. data/lib/celluloid/actor/system.rb +13 -29
  19. data/lib/celluloid/autostart.rb +5 -5
  20. data/lib/celluloid/call/async.rb +2 -0
  21. data/lib/celluloid/call/sync.rb +10 -3
  22. data/lib/celluloid/calls.rb +5 -12
  23. data/lib/celluloid/cell.rb +5 -9
  24. data/lib/celluloid/condition.rb +3 -3
  25. data/lib/celluloid/core_ext.rb +0 -2
  26. data/lib/celluloid/debug.rb +3 -0
  27. data/lib/celluloid/exceptions.rb +2 -2
  28. data/lib/celluloid/future.rb +7 -9
  29. data/lib/celluloid/group.rb +12 -8
  30. data/lib/celluloid/group/pool.rb +1 -3
  31. data/lib/celluloid/group/spawner.rb +2 -6
  32. data/lib/celluloid/internals/call_chain.rb +15 -0
  33. data/lib/celluloid/internals/cpu_counter.rb +62 -0
  34. data/lib/celluloid/internals/handlers.rb +42 -0
  35. data/lib/celluloid/internals/links.rb +38 -0
  36. data/lib/celluloid/internals/logger.rb +104 -0
  37. data/lib/celluloid/internals/method.rb +34 -0
  38. data/lib/celluloid/internals/properties.rb +32 -0
  39. data/lib/celluloid/internals/receivers.rb +64 -0
  40. data/lib/celluloid/internals/registry.rb +102 -0
  41. data/lib/celluloid/internals/responses.rb +46 -0
  42. data/lib/celluloid/internals/signals.rb +24 -0
  43. data/lib/celluloid/internals/stack.rb +74 -0
  44. data/lib/celluloid/internals/stack/dump.rb +12 -0
  45. data/lib/celluloid/internals/stack/states.rb +72 -0
  46. data/lib/celluloid/internals/stack/summary.rb +12 -0
  47. data/lib/celluloid/internals/task_set.rb +51 -0
  48. data/lib/celluloid/internals/thread_handle.rb +52 -0
  49. data/lib/celluloid/internals/uuid.rb +40 -0
  50. data/lib/celluloid/logging/incident.rb +21 -0
  51. data/lib/celluloid/logging/incident_logger.rb +147 -0
  52. data/lib/celluloid/logging/incident_reporter.rb +49 -0
  53. data/lib/celluloid/logging/log_event.rb +20 -0
  54. data/lib/celluloid/logging/ring_buffer.rb +64 -0
  55. data/lib/celluloid/mailbox.rb +22 -9
  56. data/lib/celluloid/mailbox/evented.rb +13 -5
  57. data/lib/celluloid/notifications.rb +95 -0
  58. data/lib/celluloid/pool.rb +6 -0
  59. data/lib/celluloid/probe.rb +81 -0
  60. data/lib/celluloid/proxy/abstract.rb +9 -9
  61. data/lib/celluloid/proxy/async.rb +1 -1
  62. data/lib/celluloid/proxy/block.rb +2 -2
  63. data/lib/celluloid/proxy/cell.rb +1 -1
  64. data/lib/celluloid/proxy/future.rb +2 -4
  65. data/lib/celluloid/proxy/sync.rb +1 -3
  66. data/lib/celluloid/rspec.rb +22 -33
  67. data/lib/celluloid/supervision.rb +17 -0
  68. data/lib/celluloid/supervision/configuration.rb +169 -0
  69. data/lib/celluloid/supervision/configuration/injections.rb +8 -0
  70. data/lib/celluloid/supervision/configuration/instance.rb +113 -0
  71. data/lib/celluloid/supervision/constants.rb +123 -0
  72. data/lib/celluloid/supervision/container.rb +144 -0
  73. data/lib/celluloid/supervision/container/behavior.rb +89 -0
  74. data/lib/celluloid/supervision/container/behavior/pool.rb +71 -0
  75. data/lib/celluloid/supervision/container/behavior/tree.rb +23 -0
  76. data/lib/celluloid/supervision/container/injections.rb +8 -0
  77. data/lib/celluloid/supervision/container/instance.rb +116 -0
  78. data/lib/celluloid/supervision/container/pool.rb +210 -0
  79. data/lib/celluloid/supervision/service.rb +27 -0
  80. data/lib/celluloid/supervision/supervise.rb +34 -0
  81. data/lib/celluloid/supervision/validation.rb +40 -0
  82. data/lib/celluloid/supervision/version.rb +5 -0
  83. data/lib/celluloid/system_events.rb +11 -6
  84. data/lib/celluloid/task.rb +25 -12
  85. data/lib/celluloid/task/fibered.rb +2 -0
  86. data/lib/celluloid/task/threaded.rb +3 -3
  87. data/lib/celluloid/test.rb +5 -2
  88. data/lib/celluloid/thread.rb +0 -2
  89. data/lib/celluloid/version.rb +1 -1
  90. data/spec/celluloid/block_spec.rb +29 -32
  91. data/spec/celluloid/calls_spec.rb +5 -15
  92. data/spec/celluloid/future_spec.rb +2 -2
  93. data/spec/celluloid/internals/cpu_counter_spec.rb +129 -0
  94. data/spec/celluloid/internals/links_spec.rb +43 -0
  95. data/spec/celluloid/internals/properties_spec.rb +40 -0
  96. data/spec/celluloid/internals/registry_spec.rb +62 -0
  97. data/spec/celluloid/internals/stack/dump_spec.rb +4 -0
  98. data/spec/celluloid/internals/stack/summary_spec.rb +4 -0
  99. data/spec/celluloid/internals/thread_handle_spec.rb +60 -0
  100. data/spec/celluloid/internals/uuid_spec.rb +9 -0
  101. data/spec/celluloid/logging/ring_buffer_spec.rb +36 -0
  102. data/spec/celluloid/mailbox/evented_spec.rb +11 -22
  103. data/spec/celluloid/misc/leak_spec.rb +3 -4
  104. data/spec/celluloid/notifications_spec.rb +140 -0
  105. data/spec/celluloid/probe_spec.rb +102 -0
  106. data/spec/celluloid/proxy_spec.rb +30 -30
  107. data/spec/celluloid/supervision/behavior_spec.rb +74 -0
  108. data/spec/celluloid/supervision/configuration_spec.rb +181 -0
  109. data/spec/celluloid/supervision/container_spec.rb +72 -0
  110. data/spec/celluloid/supervision/instance_spec.rb +13 -0
  111. data/spec/celluloid/supervision/root_spec.rb +28 -0
  112. data/spec/celluloid/supervision/supervisor_spec.rb +93 -0
  113. data/spec/celluloid/task/fibered_spec.rb +1 -3
  114. data/spec/celluloid/task/threaded_spec.rb +1 -3
  115. data/spec/shared/actor_examples.rb +58 -33
  116. data/spec/shared/group_examples.rb +2 -2
  117. data/spec/shared/mailbox_examples.rb +1 -1
  118. data/spec/shared/stack_examples.rb +87 -0
  119. data/spec/shared/task_examples.rb +2 -3
  120. data/spec/spec_helper.rb +2 -4
  121. data/spec/support/configure_rspec.rb +2 -3
  122. data/spec/support/coverage.rb +2 -4
  123. data/spec/support/crash_checking.rb +2 -2
  124. data/spec/support/examples/actor_class.rb +3 -8
  125. data/spec/support/examples/call_class.rb +2 -2
  126. data/spec/support/examples/container_class.rb +35 -0
  127. data/spec/support/examples/evented_mailbox_class.rb +1 -2
  128. data/spec/support/examples/stack_classes.rb +58 -0
  129. data/spec/support/examples/stack_methods.rb +23 -0
  130. data/spec/support/examples/subordinate_class.rb +19 -0
  131. data/spec/support/logging.rb +2 -34
  132. data/spec/support/loose_threads.rb +3 -16
  133. data/spec/support/reset_class_variables.rb +5 -1
  134. data/spec/support/stubbing.rb +1 -1
  135. metadata +91 -323
  136. data/culture/CONDUCT.md +0 -38
  137. data/culture/GSoC/1010-why_we_will_participate.md +0 -17
  138. data/culture/GSoC/1020-how_mentors_stay_engaged.md +0 -7
  139. data/culture/GSoC/1030-keeping_students_on_schedule.md +0 -9
  140. data/culture/GSoC/1040-getting_students_involved.md +0 -5
  141. data/culture/GSoC/1050-student_involvement_after.md +0 -5
  142. data/culture/GSoC/README.md +0 -16
  143. data/culture/Gemfile +0 -9
  144. data/culture/LICENSE.txt +0 -22
  145. data/culture/README.md +0 -22
  146. data/culture/Rakefile +0 -5
  147. data/culture/SYNC.md +0 -70
  148. data/culture/celluloid-culture.gemspec +0 -18
  149. data/culture/gems/README.md +0 -39
  150. data/culture/gems/dependencies.yml +0 -93
  151. data/culture/gems/loader.rb +0 -101
  152. data/culture/rubocop/README.md +0 -38
  153. data/culture/rubocop/lint.yml +0 -8
  154. data/culture/rubocop/metrics.yml +0 -15
  155. data/culture/rubocop/perf.yml +0 -0
  156. data/culture/rubocop/rubocop.yml +0 -5
  157. data/culture/rubocop/style.yml +0 -61
  158. data/culture/spec/gems_spec.rb +0 -2
  159. data/culture/spec/spec_helper.rb +0 -0
  160. data/culture/spec/sync_spec.rb +0 -2
  161. data/culture/sync.rb +0 -56
  162. data/culture/tasks/rspec.rake +0 -5
  163. data/culture/tasks/rubocop.rake +0 -2
  164. data/lib/celluloid/actor/manager.rb +0 -7
  165. data/lib/celluloid/backported.rb +0 -2
  166. data/lib/celluloid/current.rb +0 -2
  167. data/lib/celluloid/deprecate.rb +0 -34
  168. data/lib/celluloid/fiber.rb +0 -32
  169. data/lib/celluloid/managed.rb +0 -3
  170. data/lib/celluloid/notices.rb +0 -15
  171. data/spec/deprecate/actor_system_spec.rb +0 -72
  172. data/spec/deprecate/block_spec.rb +0 -52
  173. data/spec/deprecate/calls_spec.rb +0 -39
  174. data/spec/deprecate/evented_mailbox_spec.rb +0 -34
  175. data/spec/deprecate/future_spec.rb +0 -32
  176. data/spec/deprecate/internal_pool_spec.rb +0 -4
  177. data/spec/support/env.rb +0 -21
@@ -0,0 +1,62 @@
1
+ module Celluloid
2
+ module Internals
3
+ module CPUCounter
4
+ class << self
5
+ def cores
6
+ @cores ||= count_cores
7
+ end
8
+
9
+ def count_cores
10
+ from_result(from_env || from_sysdev || from_java || from_proc || from_win32ole || from_sysctl) || 1
11
+ end
12
+
13
+ def from_env
14
+ result = ENV["NUMBER_OF_PROCESSORS"]
15
+ result if result && !result.empty?
16
+ rescue
17
+ end
18
+
19
+ def from_sysdev
20
+ ::IO.read("/sys/devices/system/cpu/present").split("-").last.to_i + 1
21
+ rescue Errno::ENOENT
22
+ begin
23
+ result = Dir["/sys/devices/system/cpu/cpu*"].count { |n| n =~ /cpu\d+/ }
24
+ result unless result.zero?
25
+ rescue
26
+ end
27
+ rescue
28
+ end
29
+
30
+ def from_java
31
+ Java::Java.lang.Runtime.getRuntime.availableProcessors if defined? Java::Java
32
+ rescue
33
+ end
34
+
35
+ def from_proc
36
+ File.read("/proc/cpuinfo").scan(/^processor\s*:/).size if File.exist?("/proc/cpuinfo")
37
+ rescue
38
+ end
39
+
40
+ def from_win32ole
41
+ require "win32ole"
42
+ WIN32OLE.connect("winmgmts://").ExecQuery("select * from Win32_ComputerSystem").NumberOfProcessors
43
+ rescue LoadError
44
+ rescue
45
+ end
46
+
47
+ def from_sysctl
48
+ Integer `sysctl -n hw.ncpu 2>/dev/null`
49
+ rescue
50
+ end
51
+
52
+ def from_result(result)
53
+ if result
54
+ i = Integer(result.to_s[/\d+/], 10)
55
+ return i if i > 0
56
+ end
57
+ rescue
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ require "set"
2
+
3
+ module Celluloid
4
+ module Internals
5
+ class Handlers
6
+ def initialize
7
+ @handlers = Set.new
8
+ end
9
+
10
+ def handle(*patterns, &block)
11
+ patterns.each do |pattern|
12
+ handler = Handler.new pattern, block
13
+ @handlers << handler
14
+ end
15
+ end
16
+
17
+ # Handle incoming messages
18
+ def handle_message(message)
19
+ handler = @handlers.find { |h| h.match(message) }
20
+ handler.call(message) if handler
21
+ handler
22
+ end
23
+ end
24
+
25
+ # Methods blocking on a call to receive
26
+ class Handler
27
+ def initialize(pattern, block)
28
+ @pattern = pattern
29
+ @block = block
30
+ end
31
+
32
+ # Match a message with this receiver's block
33
+ def match(message)
34
+ @pattern === message
35
+ end
36
+
37
+ def call(message)
38
+ @block.call message
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,38 @@
1
+ module Celluloid
2
+ module Internals
3
+ # Linked actors send each other system events
4
+ class Links
5
+ include Enumerable
6
+
7
+ def initialize
8
+ @links = {}
9
+ end
10
+
11
+ # Add an actor to the current links
12
+ def <<(actor)
13
+ @links[actor.mailbox.address] = actor
14
+ end
15
+
16
+ # Do links include the given actor?
17
+ def include?(actor)
18
+ @links.key? actor.mailbox.address
19
+ end
20
+
21
+ # Remove an actor from the links
22
+ def delete(actor)
23
+ @links.delete actor.mailbox.address
24
+ end
25
+
26
+ # Iterate through all links
27
+ def each
28
+ @links.each { |_, actor| yield(actor) }
29
+ end
30
+
31
+ # Generate a string representation
32
+ def inspect
33
+ links = map(&:inspect).join(",")
34
+ "#<#{self.class}[#{links}]>"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,104 @@
1
+ module Celluloid
2
+ module Internals
3
+ module Logger
4
+ class WithBacktrace
5
+ def initialize(backtrace)
6
+ @backtrace = backtrace
7
+ end
8
+
9
+ def debug(string)
10
+ # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
11
+ # rubocop:disable Style/GlobalVars
12
+ Celluloid.logger.debug(decorate(string)) if $CELLULOID_DEBUG
13
+ # rubocop:enable Style/GlobalVars
14
+ end
15
+
16
+ def info(string)
17
+ Celluloid.logger.info(decorate(string))
18
+ end
19
+
20
+ def warn(string)
21
+ Celluloid.logger.warn(decorate(string))
22
+ end
23
+
24
+ def error(string)
25
+ Celluloid.logger.error(decorate(string))
26
+ end
27
+
28
+ def decorate(string)
29
+ [string, @backtrace].join("\n\t")
30
+ end
31
+ end
32
+
33
+ @exception_handlers = []
34
+
35
+ module_function
36
+
37
+ def with_backtrace(backtrace)
38
+ yield WithBacktrace.new(backtrace) if Celluloid.logger
39
+ end
40
+
41
+ # Send a debug message
42
+ def debug(string)
43
+ # !!! DO NOT INTRODUCE ADDITIONAL GLOBAL VARIABLES !!!
44
+ # rubocop:disable Style/GlobalVars
45
+ Celluloid.logger.debug(string) if Celluloid.logger && $CELLULOID_DEBUG
46
+ # rubocop:enable Style/GlobalVars
47
+ end
48
+
49
+ # Send a info message
50
+ def info(string)
51
+ Celluloid.logger.info(string) if Celluloid.logger
52
+ end
53
+
54
+ # Send a warning message
55
+ def warn(string)
56
+ Celluloid.logger.warn(string) if Celluloid.logger
57
+ end
58
+
59
+ # Send an error message
60
+ def error(string)
61
+ Celluloid.logger.error(string) if Celluloid.logger
62
+ end
63
+
64
+ # Handle a crash
65
+ def crash(string, exception)
66
+ if Celluloid.log_actor_crashes
67
+ string << "\n" << format_exception(exception)
68
+ error string
69
+ end
70
+
71
+ @exception_handlers.each do |handler|
72
+ begin
73
+ handler.call(exception)
74
+ rescue => ex
75
+ error "EXCEPTION HANDLER CRASHED:\n" << format_exception(ex)
76
+ end
77
+ end
78
+ end
79
+
80
+ # Note a deprecation
81
+ def deprecate(message)
82
+ trace = caller.join("\n\t")
83
+ warn "DEPRECATION WARNING: #{message}\n\t#{trace}"
84
+ end
85
+
86
+ # Define an exception handler
87
+ # NOTE: These should be defined at application start time
88
+ def exception_handler(&block)
89
+ @exception_handlers << block
90
+ nil
91
+ end
92
+
93
+ # Format an exception message
94
+ def format_exception(exception)
95
+ str = "#{exception.class}: #{exception}\n\t"
96
+ str << if exception.backtrace
97
+ exception.backtrace.join("\n\t")
98
+ else
99
+ "EMPTY BACKTRACE\n\t"
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,34 @@
1
+ module Celluloid
2
+ module Internals
3
+ # Method handles that route through an actor proxy
4
+ class Method
5
+ def initialize(proxy, name)
6
+ raise NoMethodError, "undefined method `#{name}'" unless proxy.respond_to? name
7
+
8
+ @proxy = proxy
9
+ @name = name
10
+ @klass = @proxy.class
11
+ end
12
+
13
+ def arity
14
+ @proxy.method_missing(:method, @name).arity
15
+ end
16
+
17
+ def name
18
+ @proxy.method_missing(:method, @name).name
19
+ end
20
+
21
+ def parameters
22
+ @proxy.method_missing(:method, @name).parameters
23
+ end
24
+
25
+ def call(*args, &block)
26
+ @proxy.__send__(@name, *args, &block)
27
+ end
28
+
29
+ def inspect
30
+ "#<Celluloid::Internals::Method #{@klass}##{@name}>"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ module Celluloid
2
+ module Internals
3
+ # Properties define inheritable attributes of classes, somewhat similar to
4
+ # Rails cattr_*/mattr_* or class_attribute
5
+ module Properties
6
+ def property(name, opts = {})
7
+ default = opts.fetch(:default, nil)
8
+ multi = opts.fetch(:multi, false)
9
+ ivar_name = "@#{name}".to_sym
10
+
11
+ singleton = class << ancestors.first; self; end
12
+ begin
13
+ singleton.send(:remove_method, name)
14
+ rescue
15
+ nil
16
+ end
17
+ singleton.send(:define_method, name) do |value = nil, *extra|
18
+ if value
19
+ value = value ? [value, *send(name), *extra].uniq : [] if multi
20
+ instance_variable_set(ivar_name, value)
21
+ elsif instance_variables.include?(ivar_name)
22
+ instance_variable_get(ivar_name)
23
+ elsif superclass.respond_to? name
24
+ superclass.send(name)
25
+ else
26
+ default
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,64 @@
1
+ require "set"
2
+ require "timers"
3
+
4
+ module Celluloid
5
+ module Internals
6
+ # Allow methods to directly interact with the actor protocol
7
+ class Receivers
8
+ def initialize(timers)
9
+ @receivers = Set.new
10
+ @timers = timers
11
+ end
12
+
13
+ # Receive an asynchronous message
14
+ def receive(timeout = nil, &block)
15
+ if Celluloid.exclusive?
16
+ Celluloid.mailbox.receive(timeout, &block)
17
+ else
18
+ receiver = Receiver.new block
19
+
20
+ if timeout
21
+ receiver.timer = @timers.after(timeout) do
22
+ @receivers.delete receiver
23
+ receiver.resume
24
+ end
25
+ end
26
+
27
+ @receivers << receiver
28
+ Task.suspend :receiving
29
+ end
30
+ end
31
+
32
+ # Handle incoming messages
33
+ def handle_message(message)
34
+ receiver = @receivers.find { |r| r.match(message) }
35
+ return unless receiver
36
+
37
+ @receivers.delete receiver
38
+ receiver.timer.cancel if receiver.timer
39
+ receiver.resume message
40
+ message
41
+ end
42
+ end
43
+
44
+ # Methods blocking on a call to receive
45
+ class Receiver
46
+ attr_accessor :timer
47
+
48
+ def initialize(block)
49
+ @block = block
50
+ @task = Task.current
51
+ @timer = nil
52
+ end
53
+
54
+ # Match a message with this receiver's block
55
+ def match(message)
56
+ @block ? @block.call(message) : true
57
+ end
58
+
59
+ def resume(message = nil)
60
+ @task.resume message
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,102 @@
1
+ module Celluloid
2
+ module Internals
3
+ # The Registry allows us to refer to specific actors by human-meaningful names
4
+ class Registry
5
+ def initialize
6
+ @root = nil # keep root out of the standard list of registered names
7
+ @actors = {} # hash of name => actor
8
+ @index = {} # hash of name => branch
9
+ @branches = {} # hash of branch => [ actors ]
10
+ @registry = Mutex.new
11
+ end
12
+
13
+ # Register an Actor
14
+ def []=(name, actor)
15
+ if name == :root
16
+ @registry.synchronize do
17
+ @root = actor
18
+ end
19
+ else
20
+ actor_singleton = class << actor; self; end
21
+ raise TypeError, "not an actor" unless actor_singleton.ancestors.include? Proxy::Abstract
22
+
23
+ # if actor.class.ancestors.include? Supervision::Container
24
+ # puts "Supervisor: #{actor.links.inspect}"
25
+ # end
26
+ @registry.synchronize do
27
+ @actors[name.to_sym] = actor
28
+ end
29
+ actor.mailbox << NamingRequest.new(name.to_sym)
30
+ end
31
+ end
32
+
33
+ def add(name, actor, branch = :services)
34
+ set(name, actor)
35
+ @registry.synchronize do
36
+ unless @branches.key? branch
37
+ @branches[branch] = []
38
+ self.class.instance_eval do
39
+ begin
40
+ remove_method(branch)
41
+ rescue
42
+ nil
43
+ end
44
+ define_method(branch) { @branches[branch] }
45
+ end
46
+ @branches[branch] << name
47
+ end
48
+ @index[name.to_sym] = branch
49
+ end
50
+ end
51
+
52
+ # Retrieve an actor by name
53
+ def [](name)
54
+ return @root if name == :root
55
+ @registry.synchronize do
56
+ @actors[name.to_sym]
57
+ end
58
+ end
59
+
60
+ def branch(name)
61
+ @registry.synchronize do
62
+ @index.select { |_a, b| b == name }
63
+ end
64
+ end
65
+
66
+ alias get []
67
+ alias set []=
68
+
69
+ def delete(name)
70
+ @registry.synchronize do
71
+ @index.delete name.to_sym
72
+ @actors.delete name.to_sym
73
+ end
74
+ end
75
+
76
+ def include?(name)
77
+ names.include? name
78
+ end
79
+
80
+ # List all registered actors by name
81
+ def names
82
+ @registry.synchronize { @actors.keys }
83
+ end
84
+
85
+ def index
86
+ @registry.synchronize { @index }
87
+ end
88
+
89
+ # removes and returns all registered actors as a hash of `name => actor`
90
+ # can be used in testing to clear the registry
91
+ def clear
92
+ hash = nil
93
+ @registry.synchronize do
94
+ hash = @actors.dup
95
+ @actors.clear
96
+ @index.clear
97
+ end
98
+ hash
99
+ end
100
+ end
101
+ end
102
+ end