lib/celluloid.rb in celluloid-0.2.2 vs lib/celluloid.rb in celluloid-0.5.0
- old
+ new
@@ -1,33 +1,164 @@
require 'logger'
-module Celluloid
- @@logger_lock = Mutex.new
- @@logger = Logger.new STDERR
+module Celluloid
+ @logger = Logger.new STDERR
- def self.logger
- @@logger_lock.synchronize { @@logger }
+ class << self
+ attr_accessor :logger # Thread-safe logger class
+
+ def included(klass)
+ klass.send :extend, ClassMethods
+ klass.send :include, Linking
+ end
+
+ # Are we currently inside of an actor?
+ def actor?
+ !!Thread.current[:actor]
+ end
+
+ # Obtain the currently running actor (if one exists)
+ def current_actor
+ actor = Thread.current[:actor_proxy]
+ raise NotActorError, "not in actor scope" unless actor
+
+ actor
+ end
end
-
- def self.logger=(logger)
- @@logger_lock.synchronize { @@logger = logger }
+
+ # Class methods added to classes which include Celluloid
+ module ClassMethods
+ # Create a new actor
+ def new(*args, &block)
+ proxy = Celluloid::Actor.new(allocate).proxy
+ proxy.send(:initialize, *args, &block)
+ proxy
+ end
+ alias_method :spawn, :new
+
+ # Create a new actor and link to the current one
+ def new_link(*args, &block)
+ current_actor = Thread.current[:actor]
+ raise NotActorError, "can't link outside actor context" unless current_actor
+
+ proxy = Celluloid::Actor.new(allocate).proxy
+ current_actor.link proxy
+ proxy.send(:initialize, *args, &block)
+ proxy
+ end
+ alias_method :spawn_link, :new_link
+
+ # Create a supervisor which ensures an instance of an actor will restart
+ # an actor if it fails
+ def supervise(*args, &block)
+ Celluloid::Supervisor.supervise(self, *args, &block)
+ end
+
+ # Create a supervisor which ensures an instance of an actor will restart
+ # an actor if it fails, and keep the actor registered under a given name
+ def supervise_as(name, *args, &block)
+ Celluloid::Supervisor.supervise_as(name, self, *args, &block)
+ end
+
+ # Trap errors from actors we're linked to when they exit
+ def trap_exit(callback)
+ @exit_handler = callback.to_sym
+ end
+
+ # Obtain the exit handler method for this class
+ def exit_handler; @exit_handler; end
end
-
- def self.included(klass)
- klass.send :include, Actor
+
+ #
+ # Instance methods
+ #
+
+ # Is this actor alive?
+ def alive?
+ Thread.current[:actor].alive?
end
+
+ # Raise an exception in caller context, but stay running
+ def abort(cause)
+ raise AbortError.new(cause)
+ end
+
+ # Terminate this actor
+ def terminate
+ Thread.current[:actor].terminate
+ end
+
+ def inspect
+ str = "#<Celluloid::Actor(#{self.class}:0x#{object_id.to_s(16)})"
+ ivars = instance_variables.map do |ivar|
+ "#{ivar}=#{instance_variable_get(ivar).inspect}"
+ end
+
+ str << " " << ivars.join(' ') unless ivars.empty?
+ str << ">"
+ end
+
+ # Send a signal with the given name to all waiting methods
+ def signal(name, value = nil)
+ Thread.current[:actor].signal name, value
+ end
+
+ # Wait for the given signal
+ def wait(name)
+ Thread.current[:actor].wait name
+ end
+
+ # Obtain the current_actor
+ def current_actor
+ Celluloid.current_actor
+ end
+
+ # Perform a blocking or computationally intensive action inside an
+ # asynchronous thread pool, allowing the caller to continue processing other
+ # messages in its mailbox in the meantime
+ def async(&block)
+ # This implementation relies on the present implementation of
+ # Celluloid::Future, which uses a Celluloid::Actor to run the block
+ Celluloid::Future.new(&block).value
+ end
+
+ # Process async calls via method_missing
+ def method_missing(meth, *args, &block)
+ # bang methods are async calls
+ if meth.to_s.match(/!$/)
+ unbanged_meth = meth.to_s.sub(/!$/, '')
+ call = AsyncCall.new(@mailbox, unbanged_meth, args, block)
+
+ begin
+ Thread.current[:actor].mailbox << call
+ rescue MailboxError
+ # Silently swallow asynchronous calls to dead actors. There's no way
+ # to reliably generate DeadActorErrors for async calls, so users of
+ # async calls should find other ways to deal with actors dying
+ # during an async call (i.e. linking/supervisors)
+ end
+
+ return # casts are async and return immediately
+ end
+
+ super
+ end
end
require 'celluloid/version'
-require 'celluloid/actor'
require 'celluloid/actor_proxy'
require 'celluloid/calls'
require 'celluloid/core_ext'
require 'celluloid/events'
require 'celluloid/linking'
require 'celluloid/mailbox'
require 'celluloid/registry'
require 'celluloid/responses'
require 'celluloid/signals'
-require 'celluloid/supervisor'
+require 'celluloid/actor'
+require 'celluloid/actor_pool'
+require 'celluloid/supervisor'
require 'celluloid/future'
+
+require 'celluloid/io'
+require 'celluloid/tcp_server'