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'