Меню


Site Logo

Назначение протокола

Протокол нужен, чтобы хранить описания сообщений, которыми может обмениваться какая-то группа модулей. Это описание выполняется на структурированном языке описания мета-данных M.

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

Протоколы состоят из описания сообщений, перечислимых типов и флагов.

Сообщение

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

Структура сообщения
  • У каждого сообщения есть уникальные имя и код класса. Они позволяют различать сообщения.
  • У сообщения может быть несколько аргументов. Они нужны, так как часто просто информации о том, что что-то случилось, бывает недостаточно.
  • У каждого аргумента есть тип, порядковый номер и уникальное имя.
  • Для некоторых аргументов можно указать значения по умолчанию (они будут использоваться, если отправитель сообщения явно не укажет требуемые значения для этих аргументов).
  • Набор возможных типов аргументов сообщений ограничен – строка (string), число (int, float, __int64), логический (bool).
  • Есть возможность использовать в сообщениях пользовательские перечислимые типы. Для этого такие типы также следует описать в протоколе.

Перечислимый тип

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

Перечислимый тип
  • У каждого перечислимого типа есть уникальное имя. Именно это имя следует использовать в качестве типа аргументов сообщения.
  • У каждого перечислимого типа есть непустое множество возможных значений. Каждое значение в этом множестве имеет уникальное имя и уникальное в пределах типа числовое значение

Флаги

При определении аргументов сообщений могут использоваться флаги. Флаги это специальный тип данных, определяющий набор именованных битовых масок.

У каждого типа флагов есть уникальное имя. Именно это имя следует использовать в качестве типа аргументов сообщения. У каждого флага есть непустое множество возможных значений. Каждое значение в этом множестве имеет уникальное имя и битовую маску.

Версии протоколов

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

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

Для удобства эволюционного развития протокола и обеспечения механизма обратной совместимости атрибут поколения в обязательном порядке устанавливается не только для всего описания протокола, но и для всех сущностей, описанных в протоколе. Это дает необходимый уровень гибкости в случаях, когда нужно иметь протоколы, содержащие несколько поколений (диалектов).

Пример описания протокола

Протокол описывается следующим образом:

: Kernel\Protocols
Имя протокола : Код протокола ; Комментарий
  Namespace : Пространство имен
  Generations : {1} 
  Enumerations ; Перечислимые типы
    ; Описание нужного числа перечислимых типов
  Messages     ; Сообщения
    ; Описание нужного числа сообщений

Пример:

: Kernel\Protocols
CrossroadController : 110
  Namespace : Uniteller.CrossroadController
  Generations : {1}
  Enumerations ; Перечислимые типы
    ColorType                | Цвет светофора
      1 : 3                  ; Поколение : 1 / Число значений : 3
        Red    : 1           |- Красный цвет 
        Yellow : 2           |- Желтый цвет
        Green  : 3           |- Зеленый цвет
  Messages ; Сообщения
    SetLight : 1             | Установить новый сигнал
      1 : 1
        Color : ColorType    |- Требуемый цвет сигнала
    Success : 2              | Команда контроллеру отработана
      1 : 0
    Fail : 3                 | Ошибка в работе контроллера (авария)
      1 : 0

Использование описания протокола

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

При кодировании модулей требуется оперировать сущностями, определенными в протоколе - флагами, перечислимыми типами, сообщениями. Описание их на целевом языке программирования естественно может быть выполнено и вручную, но при наличии описания на языке M этот этап не требует трудозатрат, так как все необходимые определения могут быть сгенерированы специальным конвертером. Например, для языка C++ по описанию протокола на языке M таким конвертером генерируется заголовочный файл с именем <Имя протокола>.h.