diff --git a/lib/dcell/actor_proxy.rb b/lib/dcell/actor_proxy.rb index 1ca8e62..58005a8 100644 --- a/lib/dcell/actor_proxy.rb +++ b/lib/dcell/actor_proxy.rb @@ -13,6 +13,13 @@ def initialize(lnode, actor, methods) raise e end end + self.class.send(:define_method, "____async_#{meth}") do |*args| + begin + ______async_method_missing meth.to_sym, *args + rescue AbortError => e + raise e + end + end end end @@ -30,5 +37,14 @@ def ______method_missing(meth, *args, &block) abort Celluloid::DeadActorError.new end end + + def ______async_method_missing(meth, *args) + message = {:actor => @actor, :meth => meth, :args => args, :async => true} + begin + @lnode.async_relay message + rescue Celluloid::Task::TerminatedError + abort Celluloid::DeadActorError.new + end + end end end diff --git a/lib/dcell/celluloid_ext.rb b/lib/dcell/celluloid_ext.rb index af86ac0..f39f625 100644 --- a/lib/dcell/celluloid_ext.rb +++ b/lib/dcell/celluloid_ext.rb @@ -26,6 +26,16 @@ def supervise_as(name, *args, &block) end end + class AsyncProxy + alias_method :____method_missing, :method_missing + def method_missing(meth, *args, &block) + if @klass == "DCell::ActorProxy" + meth = "____async_#{meth}".to_sym + end + ____method_missing meth, *args, &block + end + end + class CellProxy alias_method :____async, :async def async(meth = nil, *args, &block) diff --git a/lib/dcell/messages.rb b/lib/dcell/messages.rb index c3890c3..6c8161d 100644 --- a/lib/dcell/messages.rb +++ b/lib/dcell/messages.rb @@ -110,6 +110,10 @@ def __dispatch(actor) def dispatch actor = DCell.get_local_actor @message[:actor].to_sym + if @message[:async] + Celluloid::Actor::async actor.mailbox, @message[:meth], *@message[:args] + return + end if actor rsp = __dispatch actor else diff --git a/lib/dcell/node.rb b/lib/dcell/node.rb index f603573..f49256e 100644 --- a/lib/dcell/node.rb +++ b/lib/dcell/node.rb @@ -187,6 +187,12 @@ def relay(message) send_request request end + # Relay async message to remote actor + def async_relay(message) + request = Message::Relay.new(Thread.mailbox, message) + send_message request + end + # Send a message to another DCell node def send_message(message) begin