Skip to content

Порядок вызова плагинов не учитывает Приоритет() #363

Description

@igostv

Описание проблемы

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

Порядок итерации Соответствие в OneScript (.NET) определяется хэш-таблицей и не детерминирован. Это означает, что даже если плагин A объявляет Приоритет() = 100, а плагин B — Приоритет() = 0, нет гарантии, что A выполнится раньше B.

Воспроизведение

  1. Зарегистрировать два плагина с разными приоритетами на одно событие (например, ПослеКоммита).
  2. Запустить синхронизацию.
  3. Порядок вызова будет случайным — зависит от порядка регистрации и внутреннего хэша имени плагина.

Ожидаемое поведение

Плагины вызываются в порядке убывания Приоритет(): плагин с большим значением выполняется раньше.

Предлагаемое исправление

В методе ВыполнитьПодпискуНаСобытие перед итерацией сортировать подписчиков по Приоритет() по убыванию через ТаблицаЗначений.Сортировать:

Процедура ВыполнитьПодпискуНаСобытие(Знач ИмяПроцедурыВыполнения, ПараметрыПроцедуры)
    Для Каждого Подписчик Из ПодписчикиПоПриоритету() Цикл
        Подписчик.ВыполнитьПодписку(ИмяПроцедурыВыполнения, ПараметрыПроцедуры);
    КонецЦикла;
КонецПроцедуры

Функция ПодписчикиПоПриоритету()
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Приоритет", Новый ОписаниеТипов("Число"));
    Таблица.Колонки.Добавить("Подписчик");
    Для Каждого ЭлементИндекса Из ИндексПодписчиков Цикл
        Стр = Таблица.Добавить();
        Стр.Приоритет = ЭлементИндекса.Значение.Приоритет();
        Стр.Подписчик = ЭлементИндекса.Значение;
    КонецЦикла;
    Таблица.Сортировать("Приоритет Убыв");
    Результат = Новый Массив;
    Для Каждого Стр Из Таблица Цикл
        Результат.Добавить(Стр.Подписчик);
    КонецЦикла;
    Возврат Результат;
КонецФункции
Реализация доступна в форке: 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions