Skip to content

Latest commit

 

History

History
45 lines (23 loc) · 17.1 KB

5_reusparm.md

File metadata and controls

45 lines (23 loc) · 17.1 KB

Параметризация повторно используемых компонентов

Теперь я хотел бы описать способ, которым обобщенные компоненты FBP можно использовать повторно, используя один дополнительный, очень мощный механизм FBP, "предопределённый информационный пакет" или "IIP". IIP были разработаны Э. Лоутоном из моего старого отдела в IBM в ответ на некоторые из проблем, с которыми мы столкнулись при использовании средства параметрирования DFDM.

Допустим, вы создали компонент, подобный одному из описанных в предыдущих главах. Назовем его "Селектор". Из вышеизложенного должно быть ясно, что этот компонент может использоваться в различных контекстах, покуда он получает данные в ожидаемом формате. Поскольку компонент взаимодействует с внешним миром только через данные, отправляемые или получаемые от его портов, он может храниться в форме объекта и никогда не изменяться. Такое повторное использование часто называют переиспользованием "черного ящика", предполагая, что пользователь не может видеть внутренности компонента. Вдобавок, поскольку "черный ящик" никогда не нужно модифицировать, как только его разработчик заставит его работать, можно положиться на его правильную работу в любом контексте. Это противоположность переиспользования "белого ящика" или "чистого ящика" (уровень исходного кода), которое сегодня предоставляют большинство так называемых инструментов повторного использования. Такой тип повторного использования легко обеспечить, но, на мой взгляд, он не очень выгоден пользователям. Это может снизить стоимость разработки нового кода, но объем чистого нового кода, который необходимо поддерживать, все равно увеличивается. Более того, если ошибка обнаружена в повторно используемом коде, нет простого способа определить, безопасно ли исправить все ее экземпляры - если вы даже можете их найти (с некоторыми инструментами повторного использования вы даже не можете этого сделать).

Мы, конечно, должны мочь указать нашему компоненту-чёрному ящику "Select", какие поля следует выбирать, так как в противном случае он сможет выбирать только те поля, которые были захардкожены. Предположим, мы хотим сообщить ему, что он должен выполнять выбор содержимого 6-байтового поля, начиная со смещения 23 в каждом входящем IP, а также предоставить ему список допустимых значений поля. В классическом программировании мы делаем такие вещи, заставляя вызывающую программу указывать параметры. В FBP мы делаем нечто подобное, но нет написанной пользователем программы, в которой можно было бы указать параметры. Вместо этого у разработчика приложения есть способ указать эту информацию прямо в определении структуры приложения. Этот механизм называется предопределённым информационным пакетом (IIP). Нам также понадобится дополнительный порт на компоненте (назовем его "OPTIONS" - он может иметь любое имя). IIP может быть сгенерирован как часть структуры и связан с выбранным портом.

Как только процесс запущен, IIP превращается в обычный IP посредством компонента, отправляющего служебный вызов "receive" на порт, к которому подключен IIP. Это имеет дополнительное преимущество - порт OPTIONS также может быть загружен восходящим процессом вместо IIP, поэтому параметры компонента могут быть либо определены во время построения структуры, либо отложены до времени выполнения, без необходимости какой-либо модификации компонента. То, что компонент видит, когда он получает сообщение от порта OPTIONS, является обычным IP. В дальнейшем мы иногда будем называть это "options IP" - options IP могут начинать свою жизнь как IIP или могут быть сгенерированы вышестоящими процессами, но их функция в первую очередь заключается в управлении выполнением, а не в переносе данных (очевидно, что это не является жестким различием, и вам могут потребоваться IP, сочетающие обе функции).

И последнее, что касается IP опций: главное, что надо решить разработчику - сделать их произвольной формы или задать им жёсткую структуру - первый, как правило, будет легче задать, но для сканирования на наличие разделителей потребуется больше времени, преобразование числовых значений и т.д. Однако, поскольку эта обработка обычно выполняется только один раз, в начале выполнения, она может не иметь значения в контексте общего времени обработки. THREADS выбрала IIP свободной формы для своих "готовых" компонентов из-за фактора простоты использования. Еще одна вещь, которую вам следует учитывать, если вы решите использовать IIP свободной формы, заключается в том, что вам нужно будет принять решение о соглашениях о разделителях, например вы можете выбрать запятые или пробелы, а также можете использовать скобки для группировки наборов значений параметров. Это, в свою очередь, означает, что потребуется некоторое соглашение для определения символьных строк, которые могут содержать символы-разделители в качестве допустимых значений (старая проблема "кавычек в кавычках").

С другой стороны, пакеты фиксированной формы потребуют меньше времени на машинную обработку и позволят избежать вышеупомянутых проблем, связанных с условными обозначениями разделителей. И наоборот, они с большей вероятностью приведут к ошибкам выравнивания, и их труднее сделать открытыми. Однако в категории фиксированной формы есть и другие варианты:

  • использовать какой-либо интерфейсный инструмент для создания IIP фиксированной формы, или

  • используйте дескриптор (см. главу 11 о дескрипторах) для доступа к полям в опциях IP.

Допустим, мы хотим написать обобщенный селектор, в котором номер столбца, длина поля и допустимые значения принимаются из порта OPTIONS во время выполнения. Используя длинный неглубокий прямоугольник для представления IIP (кстати, вы не можете присоединить IIP и обычные процессы к одному и тому же соединению), мы могли бы представить наш селектор с его параметрами IIP, как показано ниже. Выбранное поле начинается со смещения 23 и имеет длину 1 байт. IP со значением A в этой позиции будут отправлены в нулевой элемент порта OUT, IP, содержащие B, будут отправлены в элемент номер 1 и так далее.

fig5_1

Фрагмент 5.1 (OPTION)

На структурной диаграмме часто бывает полезно иметь возможность отображать значения параметров прямо на картинке. Обратите внимание, что в этом примере мы показали IIP в "свободной" форме.

Чтобы преобразовать эту диаграмму для использования соединения вместо IIP, измените блок, подающий OPTIONS компоненту, и присоедините его к порту OPTIONS следующим образом:

fig5_2

Фрагмент 5.2

Для сравнения, в DFDM процессы параметризовались с помощью символьной строки переменной длины (2 байта за которыми следует символьная строка), передаваемой компоненту во время его активации (аналогично тому, как строка параметров передается в шаг "джобы" в IBM MVS). Параметры, указанные в сети и параметры, поступающие из восходящего процесса, не могли обрабатываться единообразно.

Есть общая проблема передачи параметров из "внешнего мира" в сеть. В подходе DFDM внешние параметры передавались только самой внешней структуре, и существовала система "наследования", которая позволяла структурам или компонентам более низкого уровня иметь доступ к параметрам на более высоком уровне. Хотя мы всё еще не решили эту проблему в THREADS, метод IIP должен упростить всю эту область, поскольку можно написать специальные компоненты для получения внешних параметров и передачи их в сеть в виде обычных IP.

Обобщая параметризацию компонентов, можно представить её как спектр от низкого к высокому. Низкая параметризация (несколько параметров или их отсутствие) возникает, когда компонент не имеет изменчивости - либо потому, что он запрограммирован для конкретного приложения, либо потому, что он настолько прост, что всегда выполняет одну и ту же работу одним и тем же способом. Например, во всех существующих системах FBP есть очень полезный компонент, который просто принимает и отдаёт все IP из своего первого входного порта, за которыми следуют все IP из его второго входного порта, и так далее, пока все пакеты в слотах не закончатся. В DFDM это называлось Sequencizer (некоторые мои друзья любят играть с английским языком). Этот компонент часто используется для принудительного создания последовательности данных, которые генерируются случайным образом из различных источников. Одним из примеров могут быть контрольные итоги, генерируемые различными процессами, которые затем вы хотите распечатать в фиксированном порядке в отчете. Вы знаете последовательность, в которой хотите, чтобы они отображались, но не знаете время, в которое они будут созданы. Схематично:

fig5_3

Фрагмент 5.3

Его функция настолько проста, что ему не нужен порт опций. Теперь вы можете спросить: "Почему бы просто не взять все входящие потоки данных и не объединить их в один входной порт?". Ответ в том, что вы можете это сделать, но эффект будет несколько другим. Входящие IP объединяются в последовательности "первым пришел - первым обслужен", а это не то, чего мы хотим. Так или иначе, есть и обратная сторона: поскольку данные из слота 1 задерживаются до тех пор, пока Concatenate не узнает, что слот 0 закрыт, и так далее для остальных портов, существует вероятность дедлока (взаимоблокировки). Такие ситуации не так плохи, как могут показаться, и существуют хорошо отработанные способы обнаружения мест, где они могут возникнуть, и предотвращения их до того, как они могут произойти. В FBP дедлоки рассматриваются как проблема времени разработки. Мы поговорим о причинах и предотвращении тупиковых ситуаций в в главе 16.

Компонент Select имеет средний уровень параметризации и многие из компонентов о которых мы будем говорить в этой книге подобны ему, но есть и другие, для которых параметризация столь высока, что их можно рассматривать как отдельные мини-языки.