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

Администрирование - Распределенная БД (УРИБ, УРБД)

Читая комментарии к курсу касательно новых возможностей расширений конфигурации, которые привнес релиз 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: Если вы используете обмен через файлы (в той или иной вариации), то вы можете при отправке данных центральной базе, добавлять информацию о хеше установленного расширения, а центральной проверять эту добавку и по мимо полезных данных обмена, выгружать расширение актуальной версии. Практически так-же как и БСП добавляет свои данные в сообщение обмена.

См. также

Комментарии
Сортировка: Древо
1. aspirator23 371 26.11.17 09:51 Сейчас в теме
РИБ и расширения - больная тема. В узлах они точно должны быть, если курс взят на расширения. Вероятно их все же включат в обмены. Но когда это произойдет неизвестно.
2. markers 222 26.11.17 12:18 Сейчас в теме
(1) Возможно-возможно и хоть и расширения сами по себе очень легкие (наше весит порядка 1.2 мб), но всё-же хотелось бы чтобы передавалась разница, а не целиком расширение. Но ждать когда это чудо произойдет, мы не можем. Тем-более мы всё ещё сидим на 8.3.8 ибо пока не можем перейти на более новые версии (не работает механизм авто установки новой версии тонкого клиента, скачивает и потом не устанавливает, а точек у нас много), хотя хотелось бы, в 8.3.9 и в 8.3.10 очень много вкусного есть, не говоря уже о 8.3.11
3. aspirator23 371 26.11.17 15:52 Сейчас в теме
(2) В 8.3.12 расширения через РИБ скорее всего не будет. Следовательно минимум год выкручиваться придется альтернативными способами.
4. markers 222 17.01.18 09:43 Сейчас в теме
(3) К слову, таки добавили
5. aspirator23 371 17.01.18 13:01 Сейчас в теме
Оставьте свое сообщение