Привет! Меня зовут Павел, я программист-эксперт в отделе разработки серверных решений ЮMoney. Продолжу рассказывать о том, как мы организовываем работу сложных пользовательских (и не только) процессов с применением конечных автоматов FSM (Finite-state machine). И разберём, почему наша FSM не совсем типичная и ей скорее подходит название PSM (Process-state machine).
Ссылка на первую часть статьи.
FSM как она есть
Мы выбрали FSM как основу для построения организации логики сложных процессов, потому что понимали: она отлично подходит для описания возможных переходов между состояниями.
Типичное применение FSM хорошо иллюстрирует такая схема:
Состояния машины (FSM) многократно повторяются.
Нет начала и конца (хотя может быть некоторое начальное состояние).
Но тут важны не только состояния. Важнее, что они описывают результат обработки некоторого воздействия на систему.
Вызвали start(), и FSM проверила, что её текущее состояние — Ready, только после этого она переходит в состояние Running. Контроль применимости воздействия и смена текущего состояния в результате этого воздействия — главные задачи, которые FSM позволяет легко и наглядно решать.
Много разных готовых библиотек
Конечно, для такого чёткого математического механизма уже написано большое количество библиотек. Например:
-
Компилирует декларативное описание FSM в большое количество разных ЯП (языки программирования), идеи идут от Роберта Мартина. Это, можно сказать, база, с которой стоит начинать знакомство с реализациями FSM.
-
Там почти у каждого разработчика есть своя реализация FSM.
Когда мы начинали строить свой оркестратор процессов для реализации паттерна Saga, мы быстро поняли, что нам ничего из этого не подходит. Ведь нам нужно разбить большую транзакцию на ряд мелких и локальных внутри каждого микросервиса. Если что-то идёт не так, надо применять компенсирующие действия для возврата системы в предыдущее согласованное состояние.
Математическая модель FSM не сложная, а вот условия использования логики на её основе могут сильно отличаться. В итоге каждый смотрит на FSM под своим углом и видит разную картинку.
Что мы увидели в наших процессах
Начнём сразу с примера простого процесса формирования некоторой выписки.
Есть начало и конец. Все наши операции начинаются и должны завершиться в фиксированный промежуток времени. Если этого не происходит, подключаются разработчики.
По мере перехода из состояния в состояние мы накапливаем некоторые данные. Нам важно иметь готовый удобный инструмент работы с контекстом процесса, где мы храним данные.
Управляем состоянием в большинстве случаев посредством вызова одного и того же метода — «Выполняй дальше». Потому что считаем FSM носителем знания о том, что должно происходить дальше. Клиент может вызывать и другие методы, но это зависит от текущего состояния, на основе которого клиенту каждый раз сообщается, какие методы ему доступны.
Дальше в игру вступают более приземлённые потребности обычной разработки:
FSM мы используем для проведения операций.
Операции нужно сохранять и восстанавливать, находить и понимать, какого типа каждая из них.
Операция может прервать выполнение на одном экземпляре приложения и продолжить выполнение на другом. Или может отложить выполнение до некоторого момента времени.
Таким образом, мы пошли к цели своим путём. Написали сначала простые обёртки, а потом завернули всё в декларативный стиль, о чём рассказано в первой части статьи. Но то, что у нас получилось, называть FSM уже не совсем правильно.
Реализация механизмов самой FSM сейчас занимает небольшую часть от получившейся библиотеки. Остальная часть — поддержка сериализации контекстов, синхронизация выполнения и очереди задач асинхронного выполнения, мониторинг и визуализация.
Есть вариант называть получившийся слой кода PSM (Process-state machine). FSM – модель, а PSM — реализация этой модели в контексте наших требований.
Быстрый вход в нашу FSM — визуальный дизайнер
При таком широком использовании собственной FSM в нашем коде важно дать новым сотрудникам удобный инструмент создания FSM. На основе готового редактора FSM мы сделали генератор кода, который достаточно вставить в рабочий проект — и он будет готов к работе.
Работать с редактором просто:
Можете попробовать сами поработать с нашим редактором FSM.
Где же взять саму библиотеку для запуска получившегося кода? Может быть, мы расскажем об этом в следующей части статьи. ? Пишите в комментариях, если ждёте, и подписывайтесь на блог, чтобы не пропустить.
Комментарии (5)
Ak-47
25.12.2024 12:08если правильно понял, то вы построили свой оркестратор. Понятно, что вы делали уже давно, насколько я понимаю. Но не смотрели в сторону готовых Temporal/Cadense и подобных?
dpbm Автор
25.12.2024 12:08В обсуждениях всплывал недавно Temporal, но обсуждали не фреймворк в целом, а какое у него будет узкое место. В частности, реализацию очередей для обработки тех же самых процессов. Это похоже на общую боль таких систем.
madzhuga
25.12.2024 12:08IMHO, свой оркестратор (под свои требования) написать проще, чем потом годами под чужую реализацию подстраиваться.
IIopy4uk
Пропустил первую часть статьи :\
Расскажите, пожалуйста, а чем вас не устроил SCXML и его реализации, редакторы и прочее?
dpbm Автор
В первой части я как раз рассказал что у нас уже была некоторая рабочая кодовая база, но она стала пугать нас своей сложностью. Мы стали работать с процессами, описывая каждое устойчивое состояние. В итоге это явное указание в какое состояние переходить тоже стало пугать сложностью и мы смогли перейти на декларативное описание того же самого кода.
И тут получился редактор, который не требует никаких знаний каких-то фреймворков. Но его назначение только обучение, считайте.