> This discussion has made me wonder if there is > some "generic" way of handling serializing in > druby. > > Wouldn't it be nice if you could simply mix in > a module, like > > myobj.extend(ThreadSafe) > > and then start the service normally and forget it? I always use MonitorMixin. require 'monitor' class MyClass include MonitorMixin ... def initialize super ... end def foo synchronize do ... end end end Do you want to call synchronize automatically? How is a thing like Delegator ? require 'monitor' class SyncDelegator include MonitorMixin def initialize(obj) super() preserved = ::Kernel.instance_methods preserved -= ["to_s","to_a","inspect","==","=~","==="] for t in self.type.ancestors preserved |= t.instance_methods preserved |= t.private_instance_methods preserved |= t.protected_instance_methods break if t == SyncDelegator end for method in obj.methods next if preserved.include? method eval <<-EOS def self.#{method}(*args, &block) begin synchronize do __getobj__.__send__(:#{method}, *args, &block) end rescue Exception $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` $@.delete_if{|s| /^\\(eval\\):/ =~ s} raise end end EOS end end def __getobj__ raise NotImplementError, "need to define `__getobj__'" end end class SimpleSyncDelegator<SyncDelegator def initialize(obj) super @obj = obj end def __getobj__ @obj end def __setobj__(obj) @obj = obj end end if __FILE__ == $0 class Slow def do_it p [:do_it, Time.now] sleep 2 p [:done] end end if true # sync slow = Slow.new $slow = SimpleSyncDelegator.new(slow) else # don't sync $slow = Slow.new end t1 = Thread.new do 5.times do $slow.do_it end end t2 = Thread.new do 5.times do $slow.do_it end end t1.join t2.join end