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.
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.
# 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
Moves tuple to port.
# 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.
# 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.
# 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.
# 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
# File rinda/tuplespace.rb, line 432 def take(tuple, sec=nil, &block) move(nil, tuple, sec, &block) end
Adds tuple
# 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