Class Rinda::TupleSpace
In: rinda/tuplespace.rb
Parent: Object

The Tuplespace manages access to the tuples it contains, ensuring mutual exclusion requirements are met.

The sec option for the write, take, move, read and notify methods may either be a number of seconds or a Renewer object.

Methods

move   new   notify   read   read_all   take   write  

Included Modules

DRbUndumped MonitorMixin

Public Class methods

Creates a new TupleSpace. period is used to control how often to look for dead tuples after modifications to the TupleSpace.

If no dead tuples are found period seconds after the last modification, the TupleSpace will stop looking for dead tuples.

[Source]

# File rinda/tuplespace.rb, line 392
    def initialize(period=60)
      super()
      @bag = TupleBag.new
      @read_waiter = TupleBag.new
      @take_waiter = TupleBag.new
      @notify_waiter = TupleBag.new
      @period = period
      @keeper = nil
    end

Public Instance methods

Moves tuple to port.

[Source]

# File rinda/tuplespace.rb, line 439
    def move(port, tuple, sec=nil)
      template = WaitTemplateEntry.new(self, tuple, sec)
      yield(template) if block_given?
      start_keeper
      synchronize do
        entry = @bag.find(template)
        if entry
          port.push(entry.value) if port
          @bag.delete(entry)
          notify_event('take', entry.value)
          return entry.value
        end
        raise RequestExpiredError if template.expired?

        begin
          @take_waiter.push(template)
          while true
            raise RequestCanceledError if template.canceled?
            raise RequestExpiredError if template.expired?
            entry = @bag.find(template)
            if entry
              port.push(entry.value) if port
              @bag.delete(entry)
              notify_event('take', entry.value)
              return entry.value
            end
            template.wait
          end
        ensure
          @take_waiter.delete(template)
        end
      end
    end

Registers for notifications of event. Returns a NotifyTemplateEntry. See NotifyTemplateEntry for examples of how to listen for notifications.

event can be:

‘write’:A tuple was added
‘take’:A tuple was taken or moved
‘delete’:A tuple was lost after being overwritten or expiring

The TupleSpace will also notify you of the ‘close’ event when the NotifyTemplateEntry has expired.

[Source]

# File rinda/tuplespace.rb, line 522
    def notify(event, tuple, sec=nil)
      template = NotifyTemplateEntry.new(self, event, tuple, sec)
      synchronize do
        @notify_waiter.push(template)
      end
      template
    end

Reads tuple, but does not remove it.

[Source]

# File rinda/tuplespace.rb, line 476
    def read(tuple, sec=nil)
      template = WaitTemplateEntry.new(self, tuple, sec)
      yield(template) if block_given?
      start_keeper
      synchronize do
        entry = @bag.find(template)
        return entry.value if entry
        raise RequestExpiredError if template.expired?

        begin
          @read_waiter.push(template)
          template.wait
          raise RequestCanceledError if template.canceled?
          raise RequestExpiredError if template.expired?
          return template.found
        ensure
          @read_waiter.delete(template)
        end
      end
    end

Returns all tuples matching tuple. Does not remove the found tuples.

[Source]

# File rinda/tuplespace.rb, line 500
    def read_all(tuple)
      template = WaitTemplateEntry.new(self, tuple, nil)
      synchronize do
        entry = @bag.find_all(template)
        entry.collect do |e|
          e.value
        end
      end
    end

Removes tuple

[Source]

# File rinda/tuplespace.rb, line 432
    def take(tuple, sec=nil, &block)
      move(nil, tuple, sec, &block)
    end

Adds tuple

[Source]

# File rinda/tuplespace.rb, line 405
    def write(tuple, sec=nil)
      entry = TupleEntry.new(tuple, sec)
      start_keeper
      synchronize do
        if entry.expired?
          @read_waiter.find_all_template(entry).each do |template|
            template.read(tuple)
          end
          notify_event('write', entry.value)
          notify_event('delete', entry.value)
        else
          @bag.push(entry)
          @read_waiter.find_all_template(entry).each do |template|
            template.read(tuple)
          end
          @take_waiter.find_all_template(entry).each do |template|
            template.signal
          end
          notify_event('write', entry.value)
        end
      end
      entry
    end

[Validate]