В процессе оптимизации управляемых форм одной из наиболее важных задач является минимизация контекстных серверных вызовов. Контекстный вызов (процедуры с директивой &НаСервере) заставляет платформу синхронизировать все состояние формы между клиентом и сервером. Если форма "тяжелая", содержит много реквизитов или табличных частей, такая синхронизация приводит к существенным задержкам. Часто разработчики сталкиваются с "черными ящиками" — сложными формами в типовых конфигурациях или чужом коде, где необходимо четко выявить, какие именно действия инициируют передачу контекста. Рассмотрим, как решить эту задачу с помощью Технологического журнала (ТЖ).
Прежде чем перейти к настройке, разберем ситуацию. Когда мы вызываем серверный метод без контекста (&НаСервереБезКонтекста), платформа передает только те параметры, которые мы явно указали. В случае же контекстного вызова, на сервер уходит дамп всей формы. Проблема усугубляется, если разработчик пытается вручную управлять состоянием (например, очищать коллекции на клиенте перед вызовом), но случайно оставляет контекстный вызов — в этом случае все усилия по оптимизации сводятся на нет, так как платформа все равно выполнит синхронизацию. Использование ТЖ позволяет увидеть реальную картину обращений к серверу "глазами платформы".
Основным инструментом для отслеживания клиент-серверного взаимодействия в ТЖ является событие VRSREQUEST. Это событие фиксирует каждый HTTP-запрос от тонкого или веб-клиента к серверу приложений. Проанализируем, как отличить контекстный вызов от внеконтекстного по структуре URI:
URI такого события практически всегда присутствует сегмент /e1cib/data/managedForm. Это прямой индикатор того, что запрос касается данных управляемой формы и подразумевает передачу её состояния./e1cib/call/.... Эти вызовы направлены на выполнение конкретных серверных методов (например, функций общих модулей или методов формы без контекста) и не содержат в URI упоминания структуры данных формы.Разберем пример настройки фильтра в logcfg.xml для отлова таких событий. Мы можем использовать условие like, чтобы сфокусироваться только на нужных запросах:
<event query="e=VRSREQUEST">
<condition property="URI" term="like" value=".*managedForm.*"/>
<fproperty name="URI"/>
<fproperty name="Context"/>
</event>
При анализе лога обратите внимание на свойство Action. Для контекстных вызовов часто характерно значение ExecuteExecute, которое в сочетании с путем к ресурсу формы подтверждает выполнение серверного метода с контекстом.
Если анализа URI недостаточно или вы хотите получить более веские доказательства "тяжести" вызова, проанализируем событие SCALL (Service Call). Это событие фиксирует входящий вызов на стороне сервера. Здесь критически важными являются показатели объема трафика:
InBytes составляет десятки или сотни килобайт — это гарантированный контекстный вызов. Платформа упаковала всю форму и отправила её на сервер.SCALL фиксируется имя вызываемого метода. Сопоставив MethodName из лога со своим кодом, вы сможете точно определить процедуру, которую забыли пометить директивой &НаСервереБезКонтекста.Рассмотрим пример того, как может выглядеть запись в ТЖ для контекстного вызова:
SCALL, ... ,MethodName=Execute, ... ,InBytes=154320,OutBytes=120500
В данном примере 150 Кб входящих данных для одного вызова явно указывают на передачу большого контекста формы.
Чтобы не перегружать сервер логами, но получить полную картину, настроим фильтрацию по конкретной информационной базе и исключим лишние события. Выясним причину замедлений, собирая данные по событиям VRSREQUEST и SCALL одновременно:
<config xmlns="http://v8.1c.ru/7.4/config/log">
<log location="C:\LOGS\ContextCalls" history="24">
<event query="e=VRSREQUEST">
<condition property="p:processName" term="equal" value="MyBaseName"/>
<condition property="URI" term="like" value=".*managedForm.*"/>
</event>
<event query="e=SCALL">
<condition property="p:processName" term="equal" value="MyBaseName"/>
<condition property="InBytes" term="gt" value="10000"/>
</event>
<property name="all"/>
</log>
</config>
В данном примере мы фильтруем SCALL по размеру входящих данных (более 10 Кб), что позволяет отсечь мелкие служебные вызовы и сосредоточиться на потенциально проблемных местах.
Хотя Технологический журнал является мощным инструментом посмертного анализа и мониторинга "прод-сред", не стоит забывать о превентивных мерах:
&НаСервере. Система анализа кода может выдать предупреждение, если внутри метода не используются реквизиты формы, и предложить заменить его на внеконтекстный.Interface=IID_IFormServer часто сопутствует операциям с контекстом формы.Важное замечание: Помните, что некоторые системные действия платформы (например, автоматическое обновление связанных динамических списков или проверка заполнения при некоторых сценариях) могут инициировать серверные вызовы, которые выглядят как контекстные. Их невозможно убрать простым переписыванием кода, но их важно идентифицировать для понимания общей нагрузки на систему.
Используя предложенные методы анализа VRSREQUEST и SCALL, мы можем эффективно выявлять "скрытые" контекстные вызовы даже в самых сложных и запутанных участках конфигурации, обеспечивая тем самым высокую скорость работы интерфейса для конечных пользователей.