Расширения конфигурации и РИБ, друзья или враги? Или как мы передаем расширения подчиненным РИБ узлам

Читая комментарии к курсу касательно новых возможностей расширений конфигурации, которые привнес релиз 8.3.11, на одном из известных сайтов с курсами, я обратил внимание, что коллегам приходится отказываться от расширений из-за решения перейти на РИБ. Мы сами относительно недавно начали переходить на РИБ, и мы также активно пользуемся расширениями и в этой статье я хотел бы рассказать, как мы решили эту проблему.

Компания, в которой я в данный момент работаю, решила активно пользоваться расширениями, начиная с 8.3.8 для облегчения обновления 1С Розница, вынеся в расширения большую часть интерфейсных и не только модификаций. До недавнего времени, вся наша филиальная сеть магазинов работала напрямую через веб-сервер, но из-за того что покрытие интернетом не везде хорошее, стали постепенно задумываться о разворачивании РИБ узлов в таких проблемных магазинах и тут же встал вопрос, "Что делать с расширением?" и так как мы сделали обмен через веб-сервис, решили "А почему бы не передавать расширение узлу через веб-сервис?".

Теперь я хочу представить вам то, как мы решили эту проблему.

В нашем веб-сервисе мы добавили функцию "GetExtandedConfig" с параметрами:

  • Name, Направление передачи: Входящий, Тип: string — Имя расширения
  • Hash, Направление передачи: Входящий, Тип: string — Хеш установленного расширения либо Неопределено если не установлено
  • Result, Направление передачи: Выходной, Тип: boolean — Результат операции
  • Data, Направление передачи: Выходной, Тип: ValueStorage (http://v8.1c.ru/8.1/data/core) — Двоичные данные установленного расширения центральной базы (если изменений расширения нет, то Неопределено)
  • Функция возвращает тип: string — Описание проблемы, если таковая возникла

В коде функции мы написали это:

// Соответствует операции GetExtandedConfig
Функция ПолучитьРасширениеКонфигурации(ИмяРасширения, ХешСумма, Результат, ИсхДанные)

УстановитьПривилегированныйРежим(Истина); // Пользователь вебсервиса не полноправный пользователь, компенсируем это

Если ПустаяСтрока(ИмяРасширения) Тогда

Результат = Ложь;
Возврат "Не указано имя расширения!";

КонецЕсли;

Расширения = РасширенияКонфигурации.Получить(Новый Структура("Имя", ИмяРасширения)); // Ищем расширение по полученному имени

Если Расширения.Количество() <= 0 Тогда

Результат = Ложь;
Возврат "Расширение по указанному имени не найдено!";

КонецЕсли;

ТребуемоеРасширение = Расширения[0];

Если ПустаяСтрока(ХешСумма) или ХешСумма <> Base64Строка(ТребуемоеРасширение.ХешСумма) Тогда // Либо первое получение, либо расширение изменилось

Результат = Истина;
ИсхДанные = Новый ХранилищеЗначения(ТребуемоеРасширение.ПолучитьДанные()); // Сжимать смысла нет, только ресурсы тратить
Возврат "Доступно обновление расширения";

КонецЕсли;

Результат = Истина;
Возврат "Нет обновлений расширения";

КонецФункции // ПолучитьРасширениеКонфигурации()

На "клиентской" стороне, после обмена данными через веб-сервис, проверяем, есть ли изменения в расширении и код выглядит так:

Функция ДоступнаЗащитаОтОпасныхДействий() Экспорт

СисИнфо = Новый СистемнаяИнформация;
Возврат ОбщегоНазначенияКлиентСервер.СравнитьВерсии(СисИнфо.ВерсияПриложения, "8.3.9.2033") >= 0;

КонецФункции // ДоступнаЗащитаОтОпасныхДействий()

Процедура ПроверитьИОбновитьРасширениеКонфигурации(ПроцессорОбмена) Экспорт

// ПроцессорОбмена - WS-ссылка с установленным соединением

ПоддержкаЗащитыОтОпасныхДействий = ДоступнаЗащитаОтОпасныхДействий(); // Проверим, поддерживает ли платформа защиту от опасных действий

Попытка

МассивОбновляемыхРасширений = Новый Массив;
Расширения = РасширенияКонфигурации.Получить(); // Получаем список установленных расширений

Для Каждого Расширение из Расширения Цикл

МассивОбновляемыхРасширений.Добавить(Новый Структура("Имя, УникальныйИдентификатор, ХешСумма", Расширение.Имя, Расширение.УникальныйИдентификатор, Расширение.ХешСумма));

КонецЦикла;

Если МассивОбновляемыхРасширений.Количество() <= 0 Тогда // Если расширений в базе нет, добавляем в список "предопределенное" расширение, наше основное

МассивОбновляемыхРасширений.Добавить(Новый Структура("Имя, УникальныйИдентификатор, ХешСумма", "Экстра", Неопределено, Неопределено));

ИначеЕсли ОбменДаннымиСервер.ТребуетсяУстановкаОбновления() Тогда

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

КонецЕсли;

Для Каждого Расширение из МассивОбновляемыхРасширений Цикл

Результат = Неопределено;
ВходящиеДанные = Неопределено;

// Делаем запрос к веб-сервису
СообщениеОбмена = ПроцессорОбмена.GetExtandedConfig(Расширение.Имя, Base64Строка(Расширение.ХешСумма), Результат, ВходящиеДанные);

Если Результат и Не ПустаяСтрока(СообщениеОбмена) Тогда

// Получили положительный ответ и что не было сообщений, а так-же проверим, получили ли мы сами данные
Если ВходящиеДанные = Неопределено Тогда

Продолжить;

КонецЕсли;

Иначе

Сообщить("При получении обновления расширения: " + Расширение.Имя + " была получена ошибка: " + СообщениеОбмена);
Продолжить;

КонецЕсли;

ДанныеРасширения = ВходящиеДанные.Получить(); // Получаем двоичные данные из хранилища значения

// Получены данные расширения, обработаем
Если Расширение.УникальныйИдентификатор = Неопределено Тогда // Расширение ещё не установлено

РасширениеВБазе = РасширенияКонфигурации.Создать(); // Создаем новое расширение
РасширениеВБазе.БезопасныйРежим = Ложь;

Если ПоддержкаЗащитыОтОпасныхДействий Тогда

РасширениеВБазе.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь; // Отключаем защиту от опасных действий если поддерживается

КонецЕсли;

Иначе // Получаем уже установленное расширинение старой версии

Раширения = РасширенияКонфигурации.Получить(Новый Структура("УникальныйИдентификатор", Расширение.УникальныйИдентификатор));

Если Расширения.Количество() > 0 Тогда

РасширениеВБазе = Расширения[0];

КонецЕсли;

КонецЕсли;

Если РасширениеВБазе = Неопределено Тогда

Сообщить("При обновлении раширения произошла ошибка, не удалось получить расширение: " + Расширение.Имя);
Продолжить;

КонецЕсли;

// Проверим, можно ли без ошибок применить расширение
ОшибкиВРасширении = РасширениеВБазе.ПроверитьВозможностьПрименения(ДанныеРасширения); // Возвращает ИнформацияОПроблемеПримененияРасширенияКонфигурации

Если ОшибкиВРасширении.Количество() > 0 Тогда

Сообщить("При проверке расширения " + Расширение.Имя + ", возникли ошибки:");

// Покажем полный список ошибок
Для Каждого Ошибка из ОшибкиВРасширении Цикл

Сообщить("(" + Ошибка.Важность + ") " + Расширение.Имя + ": " + Ошибка.Описание);

КонецЦикла;

// Не будем его устанавливать
Продолжить;

КонецЕсли;

// Всё хорошо! Обновляем расширение!
РасширениеВБазе.Записать(ДанныеРасширения);
Сообщить("Успешно обновлено расширение: " + Расширение.Имя + ", получена версия: " + РасширениеВБазе.Версия);

КонецЦикла;

Исключение

Сообщить("Ошибка в процедуре обновления расширения: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

КонецПопытки;

КонецПроцедуры

Вот и всё! Но, как и в каждой бочке, и тут есть ложка дёгтя, о чем и хотелось отдельно упомянуть.

Проблемы механизма

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

Заключение

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

Будут вопросы, обращайтесь!

PS: Если вы используете обмен через файлы (в той или иной вариации), то вы можете при отправке данных центральной базе, добавлять информацию о хеше установленного расширения, а центральной проверять эту добавку и по мимо полезных данных обмена, выгружать расширение актуальной версии. Практически так-же как и БСП добавляет свои данные в сообщение обмена. Ознакомится с примерами дополнения сообщения обмена своими данными, можно ознакомится в статье: https://its.1c.ru/db/metod8dev#content:2278:hdoc Кстати, 8.3.12 делает именно так, она передает полностью расширение, а не изменившуюся часть.

8 Comments

  1. aspirator23

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

    Reply
  2. markers

    (1) Возможно-возможно и хоть и расширения сами по себе очень легкие (наше весит порядка 1.2 мб), но всё-же хотелось бы чтобы передавалась разница, а не целиком расширение. Но ждать когда это чудо произойдет, мы не можем. Тем-более мы всё ещё сидим на 8.3.8 ибо пока не можем перейти на более новые версии (не работает механизм авто установки новой версии тонкого клиента, скачивает и потом не устанавливает, а точек у нас много), хотя хотелось бы, в 8.3.9 и в 8.3.10 очень много вкусного есть, не говоря уже о 8.3.11

    Reply
  3. aspirator23

    (2) В 8.3.12 расширения через РИБ скорее всего не будет. Следовательно минимум год выкручиваться придется альтернативными способами.

    Reply
  4. markers

    (3) К слову, таки добавили

    Reply
  5. aspirator23

    (4) Видел. 🙂

    Reply
  6. astrallight

    Хорошие новости! «Реализована возможность использования расширений конфигурации в распределенной информационной базе. Для плана обмена реализовано свойство ВключатьРасширенияКонфигурации.

    Для расширения конфигурации реализованы свойства ИспользуетсяВРаспределеннойИнформационнойБазе и ГлавныйУзел. Источник: http://downloads.v8.1c.ru/content//Platform/8_3_12_1567/

    Reply
  7. psamt1k

    1. Дико извиняюсь за поднятие старой темы, но

    ПоддеРжкаЗащитыОтОпасныхДействий

    2. Спасибо, за механизм. Очень помогает (количество РИБ — порядка 10)

    Reply
  8. markers

    (7) Спасибо за замечание, у меня такое бывает 😉 И хорошо что кому-то принес пользу 😉

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *