lib/celluloid.rb in celluloid-0.5.0 vs lib/celluloid.rb in celluloid-0.6.0

- old
+ new

@@ -1,6 +1,8 @@ require 'logger' +require 'thread' +require 'celluloid/fibers_are_hard' module Celluloid @logger = Logger.new STDERR class << self @@ -21,10 +23,45 @@ actor = Thread.current[:actor_proxy] raise NotActorError, "not in actor scope" unless actor actor end + + # Receive an asynchronous message + def receive(&block) + actor = Thread.current[:actor] + if actor + actor.receive(&block) + else + Thread.current.mailbox.receive(&block) + end + end + + # Create a fiber that participates in the Celluloid protocol + def fiber(*args) + actor = Thread.current[:actor] + proxy = Thread.current[:actor_proxy] + mailbox = Thread.current[:mailbox] + + Fiber.new do + Thread.current[:actor] = actor + Thread.current[:actor_proxy] = proxy + Thread.current[:mailbox] = mailbox + + yield(*args) + end + end + + # Resume a fiber that participates in the Celluloid protocol + def resume_fiber(fiber, value = nil) + actor = Thread.current[:actor] + if actor + actor.run_fiber fiber, value + else + fiber.resume value + end + end end # Class methods added to classes which include Celluloid module ClassMethods # Create a new actor @@ -62,12 +99,21 @@ # 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 + # Obtain the exit handler for this actor + attr_reader :exit_handler + + # Configure a custom mailbox factory + def use_mailbox(klass = nil, &block) + if block + define_method(:mailbox_factory, &block) + else + define_method(:mailbox_factory) { klass.new } + end + end end # # Instance methods # @@ -110,10 +156,22 @@ # Obtain the current_actor def current_actor Celluloid.current_actor end + # Obtain the Ruby object the actor is wrapping. This should ONLY be used + # for a limited set of use cases like runtime metaprogramming. Interacting + # directly with the wrapped object foregoes any kind of thread safety that + # Celluloid would ordinarily provide you, and the object is guaranteed to + # be shared with at least the actor thread. Tread carefully. + def wrapped_object; self; end + + # Receive an asynchronous message via the actor protocol + def receive(&block) + Celluloid.receive(&block) + 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 @@ -149,16 +207,18 @@ require 'celluloid/calls' require 'celluloid/core_ext' require 'celluloid/events' require 'celluloid/linking' require 'celluloid/mailbox' +require 'celluloid/receivers' require 'celluloid/registry' require 'celluloid/responses' require 'celluloid/signals' require 'celluloid/actor' require 'celluloid/actor_pool' require 'celluloid/supervisor' require 'celluloid/future' +require 'celluloid/application' require 'celluloid/io' require 'celluloid/tcp_server'