[MacRuby-devel] Dispatch gem - proxy object
Alan Skipp
al_skipp at fastmail.fm
Tue Jan 25 15:31:32 PST 2011
Hi everyone,
After the recent discussion about gcd and thread safety I took a look at the Dispatch gem (proxy object in particular). I though I'd try and improve efficiency, as all method calls are currently directed through method_missing to the delegate object.
One attempt I made was to dynamically define methods in method_missing so that subsequent calls would be more efficient. I realised the naivety of this approach when one queue was busily defining the method whilst other queues were calling method_missing - much pain ensued.
The next approach might be more promising: remove method_missing and instead define all methods of the delegate object in initialize. It appears to work most of the time, but unfortunately crashes are not infrequent. Is there anything obviously wrong about the initialize method below?
Cheers,
Alan
------
require 'delegate'
module Dispatch
class Proxy < SimpleDelegator
attr_accessor :__group__, :__queue__, :__sync__
def initialize(delegate, group=Group.new, queue=Dispatch::Queue.concurrent)
super(delegate)
@__serial__ = Dispatch::Queue.for(self)
@__group__ = group
@__queue__ = queue
@__retval__ = nil
delegate.public_methods.each do |meth|
(class << self; self; end).class_eval do
define_method meth do |*args, &block|
if block.nil? then
@__serial__.sync { @__retval__ = __getobj__.__send__(meth, *args) }
return @__retval__
end
queue = @__queue__ # copy in case it changes while in flight
@__serial__.async(@__group__) do
retval = __getobj__.__send__(meth, *args)
queue.async(@__group__) { block.call(retval) }
end
end
end
end
end
end
More information about the MacRuby-devel
mailing list