Переменные

Переменная сценария — величина, которая хранит своё значение на всём протяжении выполнения сценария. Через переменные значения переносятся из одних объектов в другие: например, запрос в базу данных заполняет переменную, а компонент «Воспроизведение числа» озвучивает её абоненту или компонент «Сравнение» выбирает по ней ветку сценария.

Все переменные определяются на этапе создания сценария. Список переменных редактируется на вкладке «Переменные» окна аргументов — там же переменная выбирается для подстановки в свойство объекта. Значение подставленной переменной вычисляется или назначается в момент работы объекта-владельца.

Ограничения на имена В именах переменных недопустимы символы [, ] и \. Дублирующие имена запрещены.

Типы переменных

  • Число — целое или десятичное;
  • Строка;
  • Дата/время;
  • Поле таблицы;
  • Служебные — только для присвоения значений.

Тип переменной после создания не редактируется — это сделано намеренно, чтобы исключить некорректные ситуации. Имя изменить можно.

Поле таблицы

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

Если столбец с таким именем не найден или не найдена строка с кодом текущего абонента — запись не производится, а чтение возвращает пустую строку. Такое усложнение объясняется тем, что сценарий создаётся независимо от задачи и таблицы и до начала выполнения на сервере ничего о них не знает.

В списке доступных переменных поля таблицы отображаются зелёным.

Режим «одно чтение, одна запись» Каждое обращение к переменной типа «Поле» — это обращение к базе. Если значение нужно в сравнениях или других промежуточных объектах, считайте его один раз, сохраните во временную переменную (число, строка, дата/время) и работайте дальше с ней. Иначе сценарий будет без нужды нагружать сервер базы данных.
Внешние таблицы, собранные запросом Переменные типа «Поле» связываются и с локальными таблицами абонентов, и с внешними. Но если внешняя таблица формируется только запросом в БД, связь не установится: поля ищутся исключительно среди столбцов указанной базовой таблицы, независимо от того, используется ли параллельно запрос. Подробности — в статье о таблицах абонентов.

Служебные переменные

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

По умолчанию служебные переменные равны −1 — это указывает обслуживающим сервисам, что учитывать их не нужно. В списке доступных переменных служебные отображаются серым.

Где живёт переменная: три области размещения

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

РазмещениеОбласть видимостиКогда применяют
Локальная Экземпляр обработчика сценариев Обычная рабочая переменная внутри одного сценария и его вложенных сценариев
Сессионная Все сценарии одной сессии — цепочки коммутаций Передача данных между IVR, диалогом и служебным сценарием в рамках одного звонка
Глобальная Все сценарии всех сессий сервера Общее состояние, чтобы служебным сценариям не приходилось кэшировать значения в базе

Локальные

Размещаются в хранилище обработчика сценариев и существуют, пока живёт обработчик. У каждого экземпляра обработчика — свой экземпляр каждой переменной, даже если экземпляры реализуют один и тот же сценарий.

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

Сессионные

Разные на низком уровне обработчики связываются между собой идентификатором сессии, который совпадает с кодом цепочки коммутаций. Сессионная переменная хранится на сервере состояний, и все сценарии одной сессии обращаются к одной области памяти.

Что это даёт при входящем звонке В главном сценарии IVR переменной присваивается значение. Звонок уходит в задачу, там запускается сценарий диалога — и он получает установленное ранее значение. Оператор переключает абонента на второй сценарий IVR, где уже доступно то, что изменил сценарий диалога. Служебный сценарий, запущенный асинхронно или как обработчик контента, тоже видит это значение.

Один и тот же сценарий, работающий параллельно в разных сессиях, использует ту же учётную запись переменной, но фактически разные области памяти — пересечений по значениям не будет.
Важно при чтении старых материалов До версии 2.8.130328 сессионные переменные назывались глобальными. Это разные вещи, и различие существенно: нынешняя глобальная переменная общая для всех сессий сервера, сессионная — только для сценариев одного звонка.

Глобальные

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

Мини-транзакции через префикс lock_ Если имя глобальной переменной начинается с lock_, после каждой отдачи её значения переменная блокируется на 100 мс. Этого достаточно, чтобы прочитавший её сценарий успел принять решение и записать новое значение, — простая защита от гонки, когда к одной переменной обращаются несколько сценариев сразу.