Skip to content

Instantly share code, notes, and snippets.

@gnufied
Created March 19, 2010 20:50
Show Gist options
  • Save gnufied/338166 to your computer and use it in GitHub Desktop.
Save gnufied/338166 to your computer and use it in GitHub Desktop.
require "thread"
KNOWN_ACTORS = {}
THREAD_POOL = []
GLOBAL_MUTEX = Mutex.new
Thread.abort_on_exception = true
class JRubyActor
attr_reader :name,:block
def initialize p_name,&block
@name = p_name
@block = block
@messages = Queue.new
@outbox = Queue.new
end
def deliver address,message
actor_instance = (Symbol === address) ? KNOWN_ACTORS[address] : address
if actor_instance
actor_instance.push_message(message.freeze,self)
else
klass = Struct.new(:message,:sender,:address)
@outbox << klass.new(message.freeze,self,address)
end
end
def react
loop do
begin
mail = @messages.pop(true)
yield(mail.message,mail.sender)
rescue
yield(nil,nil)
end
deliver_pending
end
end
def deliver_pending
unless @outbox.empty?
mail = @outbox.pop
actor_instance = KNOWN_ACTORS[mail.address]
if actor_instance
actor_instance.push_message(mail.message,mail.sender)
else
@outbox << mail
end
end
end
def push_message message,sender
klass = Struct.new(:message,:sender)
@messages << klass.new(message,sender)
end
end
def actor p_name,&block
THREAD_POOL << Thread.new(p_name,block) do
a = JRubyActor.new(p_name,&block)
GLOBAL_MUTEX.synchronize do
KNOWN_ACTORS[p_name] = a
end
a.instance_eval &block
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment