Skip to content

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

@igostv

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions