Описание проблемы
В МенеджерПодписок.os метод ВыполнитьПодпискуНаСобытие итерирует ИндексПодписчиков (Соответствие) напрямую, без учёта значения Приоритет(), которое каждый плагин обязан реализовать согласно интерфейсу ПлагинСинхронизации.
Порядок итерации Соответствие в OneScript (.NET) определяется хэш-таблицей и не детерминирован. Это означает, что даже если плагин A объявляет Приоритет() = 100, а плагин B — Приоритет() = 0, нет гарантии, что A выполнится раньше B.
Воспроизведение
- Зарегистрировать два плагина с разными приоритетами на одно событие (например,
ПослеКоммита).
- Запустить синхронизацию.
- Порядок вызова будет случайным — зависит от порядка регистрации и внутреннего хэша имени плагина.
Ожидаемое поведение
Плагины вызываются в порядке убывания Приоритет(): плагин с большим значением выполняется раньше.
Предлагаемое исправление
В методе ВыполнитьПодпискуНаСобытие перед итерацией сортировать подписчиков по Приоритет() по убыванию через ТаблицаЗначений.Сортировать:
Процедура ВыполнитьПодпискуНаСобытие(Знач ИмяПроцедурыВыполнения, ПараметрыПроцедуры)
Для Каждого Подписчик Из ПодписчикиПоПриоритету() Цикл
Подписчик.ВыполнитьПодписку(ИмяПроцедурыВыполнения, ПараметрыПроцедуры);
КонецЦикла;
КонецПроцедуры
Функция ПодписчикиПоПриоритету()
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Приоритет", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("Подписчик");
Для Каждого ЭлементИндекса Из ИндексПодписчиков Цикл
Стр = Таблица.Добавить();
Стр.Приоритет = ЭлементИндекса.Значение.Приоритет();
Стр.Подписчик = ЭлементИндекса.Значение;
КонецЦикла;
Таблица.Сортировать("Приоритет Убыв");
Результат = Новый Массив;
Для Каждого Стр Из Таблица Цикл
Результат.Добавить(Стр.Подписчик);
КонецЦикла;
Возврат Результат;
КонецФункции
Реализация доступна в форке: https://github.com/igostv/gitsync/tree/feature/plugin-priority-sorting
Практический пример
Плагин для автоматического мержа git-ветки по маркеру в комментарии хранилища 1С должен выполниться в ПослеКоммита до встроенного sync-remote (который делает git push), чтобы merge commit ушёл в тот же пакет push. Без детерминированного порядка это невозможно гарантировать.
https://github.com/igostv/gitsync-plugin-merge-branch
Описание проблемы
В
МенеджерПодписок.osметодВыполнитьПодпискуНаСобытиеитерируетИндексПодписчиков(Соответствие) напрямую, без учёта значенияПриоритет(), которое каждый плагин обязан реализовать согласно интерфейсуПлагинСинхронизации.Порядок итерации
Соответствиев OneScript (.NET) определяется хэш-таблицей и не детерминирован. Это означает, что даже если плагин A объявляетПриоритет() = 100, а плагин B —Приоритет() = 0, нет гарантии, что A выполнится раньше B.Воспроизведение
ПослеКоммита).Ожидаемое поведение
Плагины вызываются в порядке убывания
Приоритет(): плагин с большим значением выполняется раньше.Предлагаемое исправление
В методе
ВыполнитьПодпискуНаСобытиеперед итерацией сортировать подписчиков поПриоритет()по убыванию черезТаблицаЗначений.Сортировать:Практический пример
Плагин для автоматического мержа git-ветки по маркеру в комментарии хранилища 1С должен выполниться в ПослеКоммита до встроенного sync-remote (который делает git push), чтобы merge commit ушёл в тот же пакет push. Без детерминированного порядка это невозможно гарантировать.
https://github.com/igostv/gitsync-plugin-merge-branch