mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6192 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			184 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
#
 | 
						|
# rinda.rb: A Ruby implementation of the Linda distributed computing paradigm.
 | 
						|
#
 | 
						|
# <i>Introduction to Linda/rinda?</i>
 | 
						|
#
 | 
						|
# <i>Why is this library separate from <tt>drb</tt>?</i> 
 | 
						|
#
 | 
						|
# <i>Example(s)</i> 
 | 
						|
#
 | 
						|
# (See the samples directory in the Ruby distribution, from 1.8.2 onwards.)
 | 
						|
#
 | 
						|
 | 
						|
require 'drb/drb'
 | 
						|
require 'thread'
 | 
						|
 | 
						|
#
 | 
						|
# A module to implement the Linda programming paradigm in Ruby.
 | 
						|
# This is part of +drb+ (dRuby).
 | 
						|
#
 | 
						|
module Rinda
 | 
						|
  class RindaError < RuntimeError; end
 | 
						|
  class InvalidHashTupleKey < RindaError; end
 | 
						|
  class RequestCanceledError < ThreadError; end
 | 
						|
  class RequestExpiredError < ThreadError; end
 | 
						|
 | 
						|
  #
 | 
						|
  # A tuple is the elementary object in Rinda programming.
 | 
						|
  # Tuples may be matched against templates if the tuple and
 | 
						|
  # the template are the same size.
 | 
						|
  #
 | 
						|
  class Tuple
 | 
						|
    # Initialize a tuple with an Array or a Hash.
 | 
						|
    def initialize(ary_or_hash)
 | 
						|
      if Hash === ary_or_hash
 | 
						|
	init_with_hash(ary_or_hash)
 | 
						|
      else
 | 
						|
	init_with_ary(ary_or_hash)
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    # The number of elements in the tuple.
 | 
						|
    def size
 | 
						|
      @tuple.size
 | 
						|
    end
 | 
						|
 | 
						|
    # Accessor method for elements of the tuple.
 | 
						|
    def [](k)
 | 
						|
      @tuple[k]
 | 
						|
    end
 | 
						|
 | 
						|
    def fetch(k)
 | 
						|
      @tuple.fetch(k)
 | 
						|
    end
 | 
						|
 | 
						|
    # Iterate through the tuple, yielding the index or key, and the
 | 
						|
    # value, thus ensuring arrays are iterated similarly to hashes.
 | 
						|
    def each # FIXME
 | 
						|
      if Hash === @tuple
 | 
						|
	@tuple.each { |k, v| yield(k, v) }
 | 
						|
      else
 | 
						|
	@tuple.each_with_index { |v, k| yield(k, v) }
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    # Return the tuple itself -- i.e the Array or hash.
 | 
						|
    def value
 | 
						|
      @tuple
 | 
						|
    end
 | 
						|
 | 
						|
    private
 | 
						|
    def init_with_ary(ary)
 | 
						|
      @tuple = Array.new(ary.size)
 | 
						|
      @tuple.size.times do |i|
 | 
						|
	@tuple[i] = ary[i]
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    def init_with_hash(hash)
 | 
						|
      @tuple = Hash.new
 | 
						|
      hash.each do |k, v|
 | 
						|
        raise InvalidHashTupleKey unless String === k
 | 
						|
	@tuple[k] = v
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  #
 | 
						|
  # Templates are used to match tuples in Rinda.
 | 
						|
  #
 | 
						|
  class Template < Tuple
 | 
						|
    # Perform the matching of a tuple against a template.  An
 | 
						|
    # element with a +nil+ value in a template acts as a wildcard,
 | 
						|
    # matching any value in the corresponding position in the tuple.
 | 
						|
    def match(tuple)
 | 
						|
      return false unless tuple.respond_to?(:size)
 | 
						|
      return false unless tuple.respond_to?(:fetch)
 | 
						|
      return false unless self.size == tuple.size
 | 
						|
      each do |k, v|
 | 
						|
        begin
 | 
						|
          it = tuple.fetch(k)
 | 
						|
        rescue
 | 
						|
          return false
 | 
						|
        end
 | 
						|
	next if v.nil?
 | 
						|
        next if v == it
 | 
						|
        next if v === it
 | 
						|
	return false
 | 
						|
      end
 | 
						|
      return true
 | 
						|
    end
 | 
						|
    
 | 
						|
    # Alias for #match.
 | 
						|
    def ===(tuple)
 | 
						|
      match(tuple)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  
 | 
						|
  #
 | 
						|
  # <i>Documentation?</i>
 | 
						|
  #
 | 
						|
  class DRbObjectTemplate
 | 
						|
    def initialize(uri=nil, ref=nil)
 | 
						|
      @drb_uri = uri
 | 
						|
      @drb_ref = ref
 | 
						|
    end
 | 
						|
    
 | 
						|
    def ===(ro)
 | 
						|
      return true if super(ro)
 | 
						|
      unless @drb_uri.nil?
 | 
						|
	return false unless (@drb_uri === ro.__drburi rescue false)
 | 
						|
      end
 | 
						|
      unless @drb_ref.nil?
 | 
						|
	return false unless (@drb_ref === ro.__drbref rescue false)
 | 
						|
      end
 | 
						|
      true
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  #
 | 
						|
  # TupleSpaceProxy allows a remote Tuplespace to appear as local.
 | 
						|
  #
 | 
						|
  class TupleSpaceProxy
 | 
						|
    def initialize(ts)
 | 
						|
      @ts = ts
 | 
						|
    end
 | 
						|
    
 | 
						|
    def write(tuple, sec=nil)
 | 
						|
      @ts.write(tuple, sec)
 | 
						|
    end
 | 
						|
    
 | 
						|
    def take(tuple, sec=nil, &block)
 | 
						|
      port = []
 | 
						|
      @ts.move(DRbObject.new(port), tuple, sec, &block)
 | 
						|
      port[0]
 | 
						|
    end
 | 
						|
    
 | 
						|
    def read(tuple, sec=nil, &block)
 | 
						|
      @ts.read(tuple, sec, &block)
 | 
						|
    end
 | 
						|
    
 | 
						|
    def read_all(tuple)
 | 
						|
      @ts.read_all(tuple)
 | 
						|
    end
 | 
						|
    
 | 
						|
    def notify(ev, tuple, sec=nil)
 | 
						|
      @ts.notify(ev, tuple, sec)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  #
 | 
						|
  # <i>Documentation?</i>
 | 
						|
  #
 | 
						|
  class SimpleRenewer
 | 
						|
    include DRbUndumped
 | 
						|
    def initialize(sec=180)
 | 
						|
      @sec = sec
 | 
						|
    end
 | 
						|
 | 
						|
    def renew
 | 
						|
      @sec
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 | 
						|
 |