Revision: 3492 http://trac.macosforge.org/projects/ruby/changeset/3492 Author: ernest.prabhakar@gmail.com Date: 2010-02-11 14:32:06 -0800 (Thu, 11 Feb 2010) Log Message: ----------- Remove Dispatch#sync, reorder and document other methods Modified Paths: -------------- MacRuby/trunk/lib/dispatch/dispatch.rb MacRuby/trunk/spec/macruby/library/dispatch/dispatch_spec.rb Modified: MacRuby/trunk/lib/dispatch/dispatch.rb =================================================================== --- MacRuby/trunk/lib/dispatch/dispatch.rb 2010-02-11 22:12:00 UTC (rev 3491) +++ MacRuby/trunk/lib/dispatch/dispatch.rb 2010-02-11 22:32:06 UTC (rev 3492) @@ -1,55 +1,76 @@ -# Convenience methods for calling the concurrent queues +# Convenience methods for invoking GCD # directly from the top-level Dispatch module module Dispatch - # Returns a unique label based on the ancestor chain and ID of +obj+ - # plus the current time - def label_for(obj) - ancestors = obj.class.ancestors.map {|a| a.to_s} - label = ancestors.uniq.reverse.join("_").downcase - now = Time.now.to_f.to_s.gsub(".","_") - "#{label}__%x__%s" % [obj.object_id, now] + # Asynchronously run the +&block+ + # on a concurrent queue of the given (optional) +priority+ + # + # Dispatch.async {p "Do this later"} + # + def async(priority=nil, &block) + Dispatch::Queue.concurrent(priority).async &block end - # Returns a new serial queue with a unique label based on +obj+ - def queue_for(obj) - Dispatch::Queue.new Dispatch.label_for(obj) + # Asynchronously run the +&block+ inside a Future + # -- which is returned for use with +join+ or +value+ -- + # on a concurrent queue of the given (optional) +priority+ + # + # f = Dispatch.fork { 2+2 } + # f.value # => 4 + # + def fork(priority=nil, &block) + Dispatch::Future.new(priority) { block.call } end - # Run the +&block+ synchronously on a concurrent queue - # of the given (optional) +priority+ - def sync(priority=nil, &block) - Dispatch::Queue.concurrent(priority).sync &block + # Asynchronously run the +&block+ inside a Group + # -- which is created if not specified, and + # returned for use with +wait+ or +notify+ -- + # on a concurrent queue of the given (optional) +priority+ + # + # g = Dispatch.group {p "Did this"} + # g.wait # => "Did this" + # + def group(grp=nil, priority=nil, &block) + grp ||= Dispatch::Group.new + Dispatch::Queue.concurrent(priority).async(grp) { block.call } + grp end - # Run the +&block+ asynchronously on a concurrent queue - # of the given (optional) +priority+ - def async(priority=nil, &block) - Dispatch::Queue.concurrent(priority).async &block + # Returns a mostly unique reverse-DNS-style label based on + # the ancestor chain and ID of +obj+ plus the current time + # + # Dispatch.label_for(Array.new) + # => Dispatch.enumerable.array.0x2000cc2c0.1265915278.97557 + # + def label_for(obj) + names = obj.class.ancestors[0...-2].map {|a| a.to_s.downcase} + label = names.uniq.reverse.join(".") + "#{self}.#{label}.%p.#{Time.now.to_f}" % obj.object_id end - - # Run the +&block+ asynchronously on a concurrent queue - # of the given (optional) +priority+ as part of the specified +grp+ - def group(grp, priority=nil, &block) - Dispatch::Queue.concurrent(priority).async(grp) { block.call } - # Can't pass block directly for some reason + + # Returns a new serial queue with a unique label based on +obj+ + # used to serialize access to objects called from multiple threads + # + # a = Array.new + # q = Dispatch.queue_for(a) + # q.async {a << Time.now } + # + def queue_for(obj) + Dispatch::Queue.new Dispatch.label_for(obj) end - # Wrap the passed +obj+ (or its instance) inside an Actor to serialize access - # and allow asynchronous invocation plus a callback + # Wrap the passed +obj+ (or its instance, if a Class) inside an Actor + # to serialize access and allow asynchronous returns + # + # a = Dispatch.wrap(Array) + # a << Time.now # automatically serialized + # a.size # => 1 (synchronously) + # a.size {|n| p "Size=#{n}"} # => "Size=1" (asynchronously) + # def wrap(obj) Dispatch::Actor.new( (obj.is_a? Class) ? obj.new : obj) end - # Run the +&block+ asynchronously on a concurrent queue of the given - # (optional) +priority+ as part of a Future, which is returned for use with - # +join+ or +value+ - - def fork(priority=nil, &block) - Dispatch::Future.new(priority) { block.call } - # Can't pass block directly for some reason - end - - module_function :label_for, :queue_for, :async, :sync, :group, :wrap, :fork + module_function :async, :fork, :group, :label_for, :queue_for, :wrap end Modified: MacRuby/trunk/spec/macruby/library/dispatch/dispatch_spec.rb =================================================================== --- MacRuby/trunk/spec/macruby/library/dispatch/dispatch_spec.rb 2010-02-11 22:12:00 UTC (rev 3491) +++ MacRuby/trunk/spec/macruby/library/dispatch/dispatch_spec.rb 2010-02-11 22:32:06 UTC (rev 3492) @@ -15,30 +15,6 @@ @actee = Actee.new("my_actee") end - describe :label_for do - it "should return a unique label for any object" do - s1 = Dispatch.label_for(@actee) - s2 = Dispatch.label_for(@actee) - s1.should_not == s2 - end - end - - describe :queue_for do - it "should return a unique queue" do - q1 = Dispatch.queue_for(@actee) - q2 = Dispatch.queue_for(@actee) - q1.should_not == q2 - end - end - - describe :sync do - it "should execute the block Synchronously" do - $dispatch_gval = 0 - Dispatch.sync { @actee.delay_set(42) } - $dispatch_gval.should == 42 - end - end - describe :async do it "should execute the block Asynchronously" do $dispatch_gval = 0 @@ -49,6 +25,17 @@ end end + describe :fork do + it "should return a Future for tracking execution of the passed block" do + $dispatch_gval = 0 + g = Dispatch.fork { @actee.delay_set(42) } + $dispatch_gval.should == 0 + g.should be_kind_of Dispatch::Future + g.join + $dispatch_gval.should == 42 + end + end + describe :group do it "should execute the block with the specified group" do $dispatch_gval = 0 @@ -60,6 +47,22 @@ end end + describe :label_for do + it "should return a unique label for any object" do + s1 = Dispatch.label_for(@actee) + s2 = Dispatch.label_for(@actee) + s1.should_not == s2 + end + end + + describe :queue_for do + it "should return a unique queue" do + q1 = Dispatch.queue_for(@actee) + q2 = Dispatch.queue_for(@actee) + q1.should_not == q2 + end + end + describe :wrap do it "should return an Actor wrapping an instance of a passed class" do actor = Dispatch.wrap(Actee) @@ -74,16 +77,5 @@ end end - describe :fork do - it "should return a Future for tracking execution of the passed block" do - $dispatch_gval = 0 - g = Dispatch.fork { @actee.delay_set(42) } - $dispatch_gval.should == 0 - g.should be_kind_of Dispatch::Future - g.join - $dispatch_gval.should == 42 - end - end - end end