lib/celluloid/actor/system.rb
module Celluloid
extend Forwardable
def_delegators :actor_system, :[], :[]=
class Actor
class System
extend Forwardable
def_delegators :@registry, :[], :get, :[]=, :set, :delete
ROOT_SERVICES = [
{
as: :notifications_fanout,
type: Celluloid::Notifications::Fanout
},
{
as: :public_services,
type: Celluloid::Supervision::Service::Public,
accessors: [:services],
supervise: []
}
].freeze
attr_reader :registry, :group
# the root of the supervisor tree is established at supervision/root
def root_services
@tree
end
def root_configuration
@root
end
def initialize
@tree = nil
@group = Celluloid.group_class.new
@registry = Internals::Registry.new
@root = ROOT_SERVICES
end
# Launch default services
def start
within do
@root = Supervision::Service::Root.define
@tree = root_configuration.deploy
end
true
end
def within
old = Thread.current[:celluloid_actor_system]
Thread.current[:celluloid_actor_system] = self
yield
ensure
Thread.current[:celluloid_actor_system] = old
end
def get_thread
@group.get do
Thread.current[:celluloid_actor_system] = self
yield
end
end
def stack_dump
Internals::Stack::Dump.new(@group)
end
def stack_summary
Internals::Stack::Summary.new(@group)
end
def registered
@registry.names
end
def clear_registry
@registry.clear
end
def running
actors = []
@group.each do |t|
next unless t.role == :actor
actor = t.actor
# NOTE - these are in separate statements, since on JRuby t.actor may
# become nil befor .behavior_proxy() is called
next unless actor
next unless actor.respond_to?(:behavior_proxy)
proxy = actor.behavior_proxy
actors << proxy
end
actors
end
def running?
@group.active?
end
# Shut down all running actors
def shutdown
actors = running
Timeout.timeout(shutdown_timeout) do
Internals::Logger.debug "Terminating #{actors.size} #{actors.size > 1 ? 'actors' : 'actor'}..." unless actors.empty?
# Actors cannot self-terminate, you must do it for them
actors.each do |actor|
begin
actor.terminate!
rescue DeadActorError
end
end
actors.each do |actor|
begin
Actor.join(actor)
rescue DeadActorError
end
end
end
rescue Timeout::Error
Internals::Logger.error("Couldn't cleanly terminate all actors in #{shutdown_timeout} seconds!")
unless RUBY_PLATFORM == "java" || RUBY_ENGINE == "rbx"
actors.each do |actor|
begin
Actor.kill(actor)
rescue DeadActorError, MailboxDead
end
end
end
ensure
@group.shutdown
clear_registry
end
def assert_inactive
@group.assert_inactive
end
def shutdown_timeout
Celluloid.shutdown_timeout
end
end
end
end