Skip to content

Пайплайн выполнения

Igor Polyakov edited this page Mar 10, 2018 · 2 revisions

Введение

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

Исполнение пайплайна

В обычном случае исполнение пайплайна это последовательность вызовов состоящая из вызова точек прикрепления всех установленных на методе аспектов. Общая последовательность при вызове скомпонованного метода выглядит следующим образом:

  1. Выполняются все обработчики OnEntry аспектов типа MethodBoundaryAspect;
  2. Выполняется вызов основного метода
  3. Если в процессе вызова произошло исключение - см, i. Если метод выполнился без ошибок - ii
    1. Выполняются все обработчики OnException аспектов типа MethodBoundaryAspect;
    2. Выполняются все обработчики OnSuccess аспектов типа MethodBoundaryAspect;
  4. Выполняются все обработчики OnExit аспектов типа MethodBoundaryAspect.

Управление пайплайном вызова

Доступны следующие механизмы взаимодействия с пайплайном внутри каждого из обработчиков аспектов

  1. Вызов pipeline.Return() прекратит выполнение пайплайна и вернет клиенту исходного метода результат из pipeline.Context.ReturnValue, если оно было задано.
  2. Вызов pipeline.ReturnDefault() прекратит выполнение пайплайна и вернет клиенту исходного метода результат по умолчанию.
  3. Вызов pipeline.ReturnValue(object) прекратит выполнение пайплайна и вернет клиенту заданный результат. Ответственность за приведение типов лежит на стороне аспекта, в случае неприводимости типа объекта заданного результата к возвращаемому типу метода будет сгенерировано исключение.
  4. Вызов pipeline.Throw(Exception) прекратит выполнение пайплайна с исключением.
  5. Обновление результата выполнения метода без прекращения пайплайна доступно в точках OnExit, OnException, OnSuccess через изменение значения свойства pipeline.Context.ReturnValue.

Исполнение пайплайна с учетом команд управления

Если один из аспектов решил вернуть результат выполнения через Return() (или бросить исключение через Throw()) на определенном шаге пайплайна, то для данного аспекта все последующие обработчики выполнены не будут (в том числе OnExit). При этом для следующих за текущим аспектов (с большим значением Order) ни один из обработчиков вызван не будет. Что касается внешних аспектов (у которых Order меньше текущего), то для них в случае, если текущий аспект решил вернуть результат, будут вызваны обработчики OnSucess и OnExit, а для случая, когда текущий обработчик решил бросить исключение - только OnExit. Рассмотрим более детально 3 сценария на изображении. Зеленым отмечены обработчики которые выполнятся, красным - которые не выполнятся.

pipeline

Сценарий 1. Все аспекты и основной метод выполнились без ошибок.

Сценарий 2. По аргументам запроса к методу сработал аспект кеширования. Запрашиваемые данные существуют в кеше, соответственно основной метод вызывать нецелесообразно, поэтому аспект решил прервать пайплайн, запросив возврат результата в обработчике OnEntry;

Сценарий 3. Аспект транзакции не смог установить начало транзакции и решил остановить пайплайн, запросив возврат исключения в обработчике OnEntry.