| Class | Rinda::TupleSpace |
| In: |
lib/rinda/tuplespace.rb
|
| Parent: | 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 lib/rinda/tuplespace.rb, line 392
392: def initialize(period=60)
393: super()
394: @bag = TupleBag.new
395: @read_waiter = TupleBag.new
396: @take_waiter = TupleBag.new
397: @notify_waiter = TupleBag.new
398: @period = period
399: @keeper = nil
400: end
Moves tuple to port.
# File lib/rinda/tuplespace.rb, line 439
439: def move(port, tuple, sec=nil)
440: template = WaitTemplateEntry.new(self, tuple, sec)
441: yield(template) if block_given?
442: start_keeper
443: synchronize do
444: entry = @bag.find(template)
445: if entry
446: port.push(entry.value) if port
447: @bag.delete(entry)
448: notify_event('take', entry.value)
449: return entry.value
450: end
451: raise RequestExpiredError if template.expired?
452:
453: begin
454: @take_waiter.push(template)
455: while true
456: raise RequestCanceledError if template.canceled?
457: raise RequestExpiredError if template.expired?
458: entry = @bag.find(template)
459: if entry
460: port.push(entry.value) if port
461: @bag.delete(entry)
462: notify_event('take', entry.value)
463: return entry.value
464: end
465: template.wait
466: end
467: ensure
468: @take_waiter.delete(template)
469: end
470: end
471: 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 lib/rinda/tuplespace.rb, line 522
522: def notify(event, tuple, sec=nil)
523: template = NotifyTemplateEntry.new(self, event, tuple, sec)
524: synchronize do
525: @notify_waiter.push(template)
526: end
527: template
528: end
Reads tuple, but does not remove it.
# File lib/rinda/tuplespace.rb, line 476
476: def read(tuple, sec=nil)
477: template = WaitTemplateEntry.new(self, tuple, sec)
478: yield(template) if block_given?
479: start_keeper
480: synchronize do
481: entry = @bag.find(template)
482: return entry.value if entry
483: raise RequestExpiredError if template.expired?
484:
485: begin
486: @read_waiter.push(template)
487: template.wait
488: raise RequestCanceledError if template.canceled?
489: raise RequestExpiredError if template.expired?
490: return template.found
491: ensure
492: @read_waiter.delete(template)
493: end
494: end
495: end
Returns all tuples matching tuple. Does not remove the found tuples.
# File lib/rinda/tuplespace.rb, line 500
500: def read_all(tuple)
501: template = WaitTemplateEntry.new(self, tuple, nil)
502: synchronize do
503: entry = @bag.find_all(template)
504: entry.collect do |e|
505: e.value
506: end
507: end
508: end
Removes tuple
# File lib/rinda/tuplespace.rb, line 432
432: def take(tuple, sec=nil, &block)
433: move(nil, tuple, sec, &block)
434: end
Adds tuple
# File lib/rinda/tuplespace.rb, line 405
405: def write(tuple, sec=nil)
406: entry = TupleEntry.new(tuple, sec)
407: start_keeper
408: synchronize do
409: if entry.expired?
410: @read_waiter.find_all_template(entry).each do |template|
411: template.read(tuple)
412: end
413: notify_event('write', entry.value)
414: notify_event('delete', entry.value)
415: else
416: @bag.push(entry)
417: @read_waiter.find_all_template(entry).each do |template|
418: template.read(tuple)
419: end
420: @take_waiter.find_all_template(entry).each do |template|
421: template.signal
422: end
423: notify_event('write', entry.value)
424: end
425: end
426: entry
427: end
Removes dead tuples.
# File lib/rinda/tuplespace.rb, line 535
535: def keep_clean
536: synchronize do
537: @read_waiter.delete_unless_alive.each do |e|
538: e.signal
539: end
540: @take_waiter.delete_unless_alive.each do |e|
541: e.signal
542: end
543: @notify_waiter.delete_unless_alive.each do |e|
544: e.notify(['close'])
545: end
546: @bag.delete_unless_alive.each do |e|
547: notify_event('delete', e.value)
548: end
549: end
550: end
Checks the tuplespace to see if it needs cleaning.
# File lib/rinda/tuplespace.rb, line 579
579: def need_keeper?
580: return true if @bag.has_expires?
581: return true if @read_waiter.has_expires?
582: return true if @take_waiter.has_expires?
583: return true if @notify_waiter.has_expires?
584: end
Notifies all registered listeners for event of a status change of tuple.
# File lib/rinda/tuplespace.rb, line 556
556: def notify_event(event, tuple)
557: ev = [event, tuple]
558: @notify_waiter.find_all_template(ev).each do |template|
559: template.notify(ev)
560: end
561: end