класс Rinda::TupleSpace
Пространство кортежей управляет доступом к содержащимся в нём кортежам, обеспечивая соблюдение требований взаимного исключения.
Параметр sec методов write, take, move, read и notify может быть числом секунд или объектом Renewer.
Открытые методы класса
# File lib/rinda/tuplespace.rb, line 438 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
Создаёт новое пространство кортежей (TupleSpace). period используется для управления частотой поиска устаревших кортежей после изменений в пространстве кортежей (TupleSpace).
Если через period секунд после последнего изменения устаревшие кортежи не будут найдены, пространство кортежей (TupleSpace) прекратит их поиск.
Открытые методы экземпляра
# File lib/rinda/tuplespace.rb, line 485
def move(port, tuple, sec=nil)
template = WaitTemplateEntry.new(self, tuple, sec)
yield(template) if block_given?
synchronize do
entry = @bag.find(template)
if entry
port.push(entry.value) if port
@bag.delete(entry)
notify_event('take', entry.value)
return port ? nil : entry.value
end
raise RequestExpiredError if template.expired?
begin
@take_waiter.push(template)
start_keeper if template.expires
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 port ? nil : entry.value
end
template.wait
end
ensure
@take_waiter.delete(template)
end
end
end Перемещает tuple в port.
# File lib/rinda/tuplespace.rb, line 568
def notify(event, tuple, sec=nil)
template = NotifyTemplateEntry.new(self, event, tuple, sec)
synchronize do
@notify_waiter.push(template)
end
template
end Регистрирует уведомления о event. Возвращает объект NotifyTemplateEntry. Примеры прослушивания уведомлений см. в разделе NotifyTemplateEntry.
event может принимать значения:
- 'write'
-
Кортеж добавлен
- 'take'
-
Кортеж извлечён или перемещён
- 'delete'
-
Кортеж потерян в результате перезаписи или истечения срока действия
Пространство кортежей (TupleSpace) также уведомит вас о событии 'close', когда срок действия NotifyTemplateEntry истечёт.
# File lib/rinda/tuplespace.rb, line 522
def read(tuple, sec=nil)
template = WaitTemplateEntry.new(self, tuple, sec)
yield(template) if block_given?
synchronize do
entry = @bag.find(template)
return entry.value if entry
raise RequestExpiredError if template.expired?
begin
@read_waiter.push(template)
start_keeper if template.expires
template.wait
raise RequestCanceledError if template.canceled?
raise RequestExpiredError if template.expired?
return template.found
ensure
@read_waiter.delete(template)
end
end
end Читает tuple, но не удаляет его.
# File lib/rinda/tuplespace.rb, line 546
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 Возвращает все кортежи, соответствующие tuple. Найденные кортежи не удаляются.
# File lib/rinda/tuplespace.rb, line 478 def take(tuple, sec=nil, &block) move(nil, tuple, sec, &block) end
Удаляет tuple
# File lib/rinda/tuplespace.rb, line 451
def write(tuple, sec=nil)
entry = create_entry(tuple, sec)
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)
start_keeper if entry.expires
@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 Добавляет tuple
Закрытые методы экземпляра
# File lib/rinda/tuplespace.rb, line 578 def create_entry(tuple, sec) TupleEntry.new(tuple, sec) end
# File lib/rinda/tuplespace.rb, line 585
def keep_clean
synchronize do
@read_waiter.delete_unless_alive.each do |e|
e.signal
end
@take_waiter.delete_unless_alive.each do |e|
e.signal
end
@notify_waiter.delete_unless_alive.each do |e|
e.notify(['close'])
end
@bag.delete_unless_alive.each do |e|
notify_event('delete', e.value)
end
end
end Удаляет устаревшие кортежи.
# File lib/rinda/tuplespace.rb, line 632 def need_keeper? return true if @bag.has_expires? return true if @read_waiter.has_expires? return true if @take_waiter.has_expires? return true if @notify_waiter.has_expires? end
Проверяет, нуждается ли пространство кортежей в очистке.
# File lib/rinda/tuplespace.rb, line 606
def notify_event(event, tuple)
ev = [event, tuple]
@notify_waiter.find_all_template(ev).each do |template|
template.notify(ev)
end
end Уведомляет всех зарегистрированных для event слушателей об изменении состояния tuple.
# File lib/rinda/tuplespace.rb, line 616
def start_keeper
return if @keeper && @keeper.alive?
@keeper = Thread.new do
while true
sleep(@period)
synchronize do
break unless need_keeper?
keep_clean
end
end
end
end Создаёт поток, который сканирует пространство кортежей в поисках просроченных кортежей.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.