Цепочка обработчиков

Цепочка обработчиков в Iron реализует модель последовательной обработки запроса, при которой каждый модуль получает управление по очереди, может модифицировать контекст выполнения и либо передать управление дальше, либо завершить выполнение.

Основная идея заключается в разделении логики на независимые функции-обработчики, каждая из которых выполняет строго определённую задачу:

  • разбор входящего запроса
  • валидация данных
  • авторизация
  • бизнес-логика
  • формирование ответа

Каждый обработчик получает единый объект контекста и функцию перехода к следующему звену цепи.


Контекст выполнения

Центральным элементом цепочки является объект контекста. Он существует на протяжении всего жизненного цикла запроса и передаётся по цепочке без копирования.

Контекст обычно содержит:

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

Ключевой принцип: все изменения состояния происходят через контекст, а не через глобальные переменные.


Структура обработчика

Каждый обработчик представляет собой функцию с фиксированной сигнатурой:

  • контекст
  • next-функция

Обработчик может:

  • выполнить синхронную логику
  • выполнить асинхронные операции
  • завершить цепочку без вызова следующего обработчика
  • передать управление дальше

Пример логики поведения:

  • если данные некорректны → завершить цепочку
  • если требуется дополнительная обработка → вызвать next
  • если ошибка → пробросить исключение

Последовательность выполнения

Цепочка выполняется строго по порядку регистрации обработчиков.

Поведение можно описать следующим образом:

  1. создаётся контекст запроса
  2. вызывается первый обработчик
  3. при вызове next управление передаётся следующему
  4. процесс повторяется до конца цепочки
  5. формируется итоговый результат

Любое прерывание цепочки останавливает дальнейшее выполнение.


Синхронные и асинхронные обработчики

Iron поддерживает смешанную модель выполнения, где цепочка может содержать как синхронные, так и асинхронные функции.

Синхронные обработчики

Используются для быстрых операций:

  • проверка формата данных
  • простая маршрутизация
  • изменение контекста

Такие обработчики выполняются мгновенно и не блокируют поток ожидания.

Асинхронные обработчики

Применяются при необходимости взаимодействия с внешними системами:

  • запросы к базе данных
  • HTTP-вызовы
  • файловые операции

Асинхронный обработчик обязан корректно завершить выполнение до передачи управления дальше.


Управление потоком цепочки

Контроль выполнения цепочки осуществляется через вызов функции перехода.

Существует несколько сценариев:

Передача управления дальше

Обработчик завершает свою работу и вызывает следующий элемент цепочки.

Прерывание цепочки

Если дальнейшая обработка не требуется, цепочка завершается без вызова последующих обработчиков.

Перехват выполнения

Обработчик может изменить поведение цепочки, например:

  • заменить результат
  • модифицировать контекст
  • скорректировать маршрут выполнения

Ошибки в цепочке

Ошибки в Iron обрабатываются как отдельный поток выполнения.

При возникновении исключения:

  • выполнение текущего обработчика прерывается
  • управление передаётся обработчику ошибок
  • формируется ответ с учётом контекста ошибки

Обработчики ошибок имеют ту же структуру, но получают дополнительную информацию о причине сбоя.


Композиция обработчиков

Цепочка в Iron строится как композиция независимых модулей. Это позволяет:

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

Композиция обеспечивает гибкость архитектуры и упрощает масштабирование приложения.


Вложенные цепочки

Iron поддерживает возможность вложенных цепочек, когда один обработчик запускает собственную последовательность обработки.

Такой подход используется для:

  • сегментации логики
  • повторного использования наборов middleware
  • изоляции функциональных блоков

Вложенные цепочки работают на том же контексте или на его производной копии, в зависимости от конфигурации.


Приоритет выполнения

Порядок регистрации обработчиков напрямую определяет их приоритет.

Типичные сценарии:

  • первыми выполняются системные middleware
  • затем логика безопасности
  • далее бизнес-обработчики
  • в конце формирование ответа

Нарушение порядка регистрации может привести к некорректной работе цепочки.


Изменение контекста в цепочке

Каждый обработчик имеет право модифицировать контекст.

На практике это используется для:

  • добавления пользовательских данных после авторизации
  • хранения промежуточных вычислений
  • передачи результатов между этапами обработки

Важно, что изменения контекста сохраняются для всех последующих обработчиков.


Отладка цепочки обработчиков

При разработке сложных цепочек особое значение имеет наблюдаемость.

Часто используются подходы:

  • логирование входа и выхода каждого обработчика
  • трассировка контекста
  • измерение времени выполнения
  • фиксация состояния между шагами

Это позволяет точно определить место возникновения ошибок или замедлений.


Паттерны использования

Цепочка обработчиков в Iron обычно реализует несколько архитектурных паттернов:

Middleware pipeline

Каждый обработчик расширяет или модифицирует запрос.

Chain of Responsibility

Запрос последовательно передаётся между обработчиками до момента обработки.

Decorator-like поведение

Каждый слой может оборачивать предыдущий, добавляя дополнительную логику.


Типичные ошибки при проектировании цепочки

При работе с цепочками часто встречаются следующие проблемы:

  • отсутствие вызова next → зависание выполнения
  • чрезмерное разрастание контекста
  • нарушение порядка обработчиков
  • смешивание бизнес-логики и инфраструктурного кода
  • дублирование функциональности в разных слоях

Такие ошибки приводят к снижению предсказуемости системы и усложняют поддержку.


Производительность цепочки

Производительность зависит от количества обработчиков и их сложности.

Основные факторы влияния:

  • число переходов между обработчиками
  • наличие асинхронных операций
  • объём данных в контексте
  • частота модификации состояния

Оптимизация обычно сводится к сокращению лишних слоёв и минимизации операций внутри middleware.