Программирование на языке Ruby - [228]

Шрифт
Интервал

— это большое объектное пространство, наполненное кортежами, нечто вроде «информационного супа».

Пока реализация пространства кортежей кажется ничем не примечательной. Но все становится гораздо интереснее, стоит лишь осознать, что к нему могут обращаться многие клиенты и доступ должен синхронизироваться. Короче говоря, это распределенная сущность; любой клиент может читать из пространства кортежей или писать в него, то есть его можно рассматривать как большое распределенное хранилище или даже способ коммуникации.

Первой реализацией пространства кортежей был проект Linda — исследование в области параллельного программирования, выполненное в Йельском университете в 1980-х годах. Реализация на языке Ruby (конечно, на основе библиотеки >drb), естественно, называется Rinda.

Кортеж в Rinda может быть массивом или хэшем. На хэш налагается дополнительное ограничение: все ключи должны быть строками. Вот несколько примеров простых кортежей:

>t1 = [:add, 5, 9]

>t2 = [:name, :add_service, Adder.new, nil]

>t3 = { 'type' => 'add', 'value_1' => 5, 'value_2' => 9 }

Элемент кортежа может быть произвольным объектом; это работает, потому что >drb умеет выполнять маршалинг и демаршалинг объектов Ruby. (Конечно, необходимо либо включить модуль >DRbUndumped, либо сделать определения объектов доступными серверу.)

Пространство объектов создается методом >new:

>require 'rinda/tuplespace'


>ts = Rinda::TupleSpace.new

># ...

Поэтому сервер выглядит так:

>require 'rinda/tuplespace'


>ts = Rinda::TupleSpace.new

>DRb.start_service("druby://somehost:9000", ts)

>gets # Нажать Enter для завершения сервера.

А клиент — так:

>require 'rinda/tuplespace'


>DRb.start_service

>ts = DRbObject.new(nil, "druby://somehost:9000")

># ...

К пространству кортежей в Rinda применимы пять операций: >read, >read_all, >write, >take и >notify.

Операция чтения >read позволяет получить один кортеж. Но способ идентификации кортежа не вполне очевиден: необходимо задать кортеж, соответствующий искомому; при этом >nil соответствует любому значению.

>t1 = ts.read [:Sum,nil] # Может извлечь, например, [:Sum, 14].

Обычно операция >read блокирует выполнение программы (для синхронизации). Чтобы быстро проверить существование кортежа, можно выполнить неблокирующее чтение, задав нулевой тайм-аут:

>t2 = ts.read [:Result,nil],0 # Возбуждает исключение, если кортеж

># не существует.

Если мы точно знаем или предполагаем, что образцу будет соответствовать не один, а несколько кортежей, можно воспользоваться методом >read_all, который возвращает массив:

>tuples = ts.read_all [:Foo, nil, nil]

>tuples.each do |t|

># ...

>end

Метод >read_all не принимает второго параметра. Он всегда блокирует программу, если не найдено ни одного подходящего кортежа.

Операция >take — это чтение, за которым следует удаление. Иными словами, метод >take удаляет кортеж из пространства кортежей и возвращает его вызывающей программе:

>t = ts.take [:Sum, nil] # Кортежа больше нет в пространстве кортежей.

Может возникнуть вопрос, почему не существует явного способа удаления. Надо полагать, что этой цели служит метод take.

Метод >write помещает кортеж в пространство кортежей. Второй параметр показывает, сколько секунд кортеж может существовать, прежде чем система сочтет, что срок его хранения истек. (По умолчанию его значение равно >nil, то есть срок хранения не ограничен.)

>ts.write [:Add, 5, 9]      # Хранить "вечно".

>ts.write [:Foo, "Bar"], 10 # Хранить 10 секунд.

Здесь уместно будет сказать несколько слов о синхронизации. Предположим, что два клиента пытаются одновременно забрать (>take) один и тот же кортеж. Одному это удастся, а другой будет заблокирован. Если первый клиент затем изменит кортеж и запишет (>write) его обратно в хранилище, то второй получит модифицированную версию. Можно считать, что операция «обновления» — это последовательность >take и >write, которая не приводит к потере данных. Конечно, как и при любом варианте многопоточного программирования, нужно позаботиться о том, чтобы не возникали тупиковые ситуации.

Метод >notify позволяет следить за пространством кортежей и получать уведомления, когда над интересующим вас кортежем была выполнена какая-то операция. Этот метод возвращает объект >NotifyTemplateEntry и может наблюдать на операциями четырех видов:

• >write;

• >take;

• удаление (когда истекает срок хранения кортежа);

• закрытие (когда истекает срок хранения объекта >NotifyTemplateEntry).

Поскольку операция чтения ничего не изменяет, то система не поддерживает уведомлений о чтениях. В листинге 20.4 приведен пример использования notify.

Листинг 20.4. Уведомление в системе Rinda

>require 'rinda/tuplespace'


>ts = Rinda::TupleSpace.new


>alberts = ts.notify "write", ["Albert", nil]

>martins = ts.notify "take", ["Martin", nil]


>thr1 = Thread.new do

> alberts.each {|op,t| puts "#{op}: #{t.join(' ')}" }

>end


>thr2 = Thread.new do

> martins.each {|op,t| puts "#{op}: #{t.join(' ')}" }

>end


>sleep 1


>ts.write ["Martin", "Luther"]

>ts.write ["Albert", "Einstein"]

>ts.write ["Martin", "Fowler"]

>ts.write ["Alberf, "Schweitzer"]

>ts.write ["Martin", "Scorsese"]

>ts.take ["Martin", "Luther"]


># Выводится:

># write: Albert Einstein


Рекомендуем почитать
Графика DirectX в Delphi

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Вторая жизнь старых компьютеров

Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.


DirectX 8. Начинаем работу с DirectX Graphics

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.