This post originated from an RSS feed registered with Ruby Buzz
by Andrew Johnson.
Original Post: Asynchronous Sequential Messages
Feed Title: Simple things ...
Feed URL: http://www.siaris.net/index.cgi/index.rss
Feed Description: On programming, problem solving, and communication.
The Io language has asynchronous
messages that return transparent futures — asynchronous messages are
put in a per-object queue and processed sequentially by a lightweight
thread (coroutine). The return value is a transparent future which _turns
into_ the actual result when it becomes available (using the future blocks
if the result isn’t ready). I thought it might be interesting to POC
the idea in Ruby code:
require 'thread'
class Async
@@keep = %w-__id__ __send__-
(instance_methods - @@keep).each{|m| undef_method m}
def initialize(&blk)
@th = Thread.new(&blk)
@th.abort_on_exception = true
at_exit {@th.join}
end
def method_missing(sym, *args, &blk)
__getobj__.__send__(sym, *args, &blk)
end
def __getobj__
@obj ||= @th.value
end
# control/status messages
def arun
@th.run
self
end
def await
@th.join
end
def aready?
! @th.alive?
end
def aresult_to(obj,meth)
Async.new {obj.send(meth,__getobj__)}
end
end
class Object
def async(msg,*args,&blk)
@async_queue ||= Queue.new
fut = Async.new {Thread.stop;self.send(msg,*args,&blk)}
@async_queue << fut
@async_thread ||= Thread.new do
loop{@async_queue.pop.arun.await; Thread.pass}
end
fut
end
end
__END__
Each object gets its own queue for asynchronous messages, which are handled
in turn (FIFO). Thread control is explicitly passed upon completion of an
asynchronous message (control can also be passed within an asynchronous
message). The return value is a proxy-future that will block when used
(aside from a few control messages) until the result is ready and then
proxy that result. This version also allows for the result of an
asynchronous message to be automatically passed to another object via the
aresult_to method.
There is probably more wrong than right with this proof-of-concept
(deadlock, exceptions, garbage collection, etc.). Still, it was a cute
little exercise — and I should mention that I freely borrowed ideas
from Jim Weirich’s BlankSlate
and kjana’s UDelegator (with
its own versions of futures and promises).