Исходный код вики Движок cccc1808. ProcessEngine

Версия 1.20 от Alexandr Fokin на 2026/04/10 15:00

Скрыть последних авторов
Alexandr Fokin 1.2 1 |(% style="width:132px" %)Теги поиска|(% style="width:1301px" %)(((
2 cccc1808. ProcessEngine, cccc1808.ProcessEngine
Alexandr Fokin 1.1 3 Очередь задач, Система обработки процессов, Движок обработки процессов.
Alexandr Fokin 1.2 4 [[Процесс>>doc:Архитектура и модели.Модели.Процесс.WebHome]]
5 )))
Alexandr Fokin 1.10 6 |(% style="width:132px" %) |(% style="width:1301px" %)Универсальный движок для выполнения процессов и очередей задач, позволяющий комбинировать несколько подходов к обработке (см особенности).
7 |(% style="width:132px" %) |(% style="width:1301px" %)Процесс является единицей выполнения.
8 Система триггеров используется для таймеров и передачи сигналов для процессов (с оптимизацией нагрузки).
Alexandr Fokin 1.18 9 |(% style="width:132px" %)Разветывание|(% style="width:1301px" %)(((
10 |(% style="width:150px" %)База данных|(% style="width:1177px" %)(((
11 Для надежного хранения данных процессов и триггеров.
12
13 * Сейчас есть реализация под EntityFramework.
14 * Но модель позволяет сделать реализацию под другие решения (LinqToDb или чистый Ado.Net).
15
16
17
18 Для текущей реализации в качестве хранилище может выступать БД, поддерживающая:
19
20 * транзакции
21 * savepoint (если используются)
22 * updatelock
23 * updatelock skip locked
24 * sharelock (можно обойтись без него)
25 )))
26 |(% style="width:150px" %)Брокер сообщений|(% style="width:1177px" %)(((
27 Используется для накопления и доставки TriggerEvent.
28
29 * Сейчас есть реализация под [[Apache Kafka>>doc:Разработка.Брокеры сообщений.Apache Kafka.WebHome]]
Alexandr Fokin 1.19 30 * Если запускать в одном экземпляре, то можно обойтись inmemory реализаций.
Alexandr Fokin 1.18 31 )))
32 )))
Alexandr Fokin 1.1 33 |(% style="width:132px" %)Особенности|(% style="width:1301px" %)(((
Alexandr Fokin 1.6 34 |(% style="width:159px" %)Батчинг|(% style="width:1168px" %)(((
Alexandr Fokin 1.1 35 Возможность использовать и комбинировать разные типы выполнения как
36
37 * (1 транзакция - 1 процесс),
38 * (1 транзакция - N процессов).
39 )))
Alexandr Fokin 1.6 40 |(% style="width:159px" %)Изоляция шагов и процессов (внутри оной транзакции)|(% style="width:1168px" %)(((
Alexandr Fokin 1.1 41 * Изоляция через db savepoint.
42 * Для [[EntityFramework ~| EntityFrameworkCore>>doc:Разработка.NET.Работа с БД.EntityFramework | EntityFrameworkCore.WebHome]] возможность делать InMemory снимок [[Создание снимка ChangeTracker>>doc:Разработка.NET.Работа с БД.EntityFramework | EntityFrameworkCore.Сценарии и проблемы.Создание снимка ChangeTracker.WebHome]].
43 )))
Alexandr Fokin 1.18 44 |(% style="width:159px" %) |(% style="width:1168px" %)(((
Alexandr Fokin 1.1 45 * Сейчас есть реализация под EntityFramework.
46 * Но модель позволяет сделать реализацию под другие решения (LinqToDb или чистый Ado.Net).
Alexandr Fokin 1.7 47
48 Для текущей реализации в качестве хранилище может выступать БД, поддерживающая:
49
50 * транзакции
51 * savepoint (если используются)
52 * updatelock
53 * updatelock skip locked
54 * sharelock (можно обойтись без него)
Alexandr Fokin 1.1 55 )))
Alexandr Fokin 1.6 56 |(% style="width:159px" %)Передача сигналов для процессов через систему триггеров.|(% style="width:1168px" %)(((
Alexandr Fokin 1.1 57 В том числе для передачи сигналов реализована система триггеров.
Alexandr Fokin 1.14 58 Она позволяет оптимизировать операции с БД и уменьшить конкуренцию между процессами за общее состояние (родительский процесс).
Alexandr Fokin 1.1 59
60 см. пример 1.
61 )))
Alexandr Fokin 1.11 62 |(% style="width:159px" %)Перехват ошибок|(% style="width:1168px" %)Перехват и обработка ошибок, если процесс выкинул exception в движок. Реализацию простого retry с задержкой (создается триггер на следующую попытку).
Alexandr Fokin 1.6 63 |(% style="width:159px" %)Параллельное выполнение|(% style="width:1168px" %)Допускается запуск нескольких раннеров (на разных нодах), работающих с одной таблицей процессов для распределения нагрузки между ними.
Alexandr Fokin 1.9 64 Допускается фильтрация типов процессов между нодами (чтобы нода выполняла только определенные типы процессов, в том числе по приоритету).
Alexandr Fokin 1.6 65 Доступно для раннеров процессов и триггеров.
Alexandr Fokin 1.9 66 \\Также возможна частичная поставка новой версии процесса и этот процесс будет браться в обработку только ограниченным количеством новых нод исполнителей.
67 \\В перспективе возможны решения с шардированием.
Alexandr Fokin 1.6 68 |(% style="width:159px" %)Soft timeout|(% style="width:1168px" %)Возможность указывать soft timeout, который будет мягко приостанавливать цикл (внутри шага процесса), чтобы ограничить общее время транзакции (не делать транзакции долгими (например горизонт postgres)). 
Alexandr Fokin 1.1 69 Например родительский процесс может создать N/2 дочерних процессов за 1 сессию и N/2 за 2 сессию выполнения.
Alexandr Fokin 1.20 70 |(% style="width:159px" %)Range preload process data|(% style="width:1168px" %)(Необязательно) возможность в начале сессии обработки пакетно предзагружать данные и бизнес сущности для процессов (Range query) из обрабатываемого батча для оптимизации чтения (если используется обработка пакета процессов в одной транзакции).
Alexandr Fokin 1.1 71 )))
72 |(% style="width:132px" %)Примеры|(% style="width:1301px" %)(((
73 |(% style="width:32px" %)1|(% style="width:171px" %)Родительский процесс, N дочерних процессов.|(% style="width:1066px" %)(((
74 |(% style="width:870px" %)(((
75 1. Родительский процесс создает триггер со счетчиком N, создает и запускает дочерние процессы, засыпает.
76 1. Дочерние процесс при завершении публикует TriggerEvent.
77 1. TriggerConsumerRunner периодически считывает батч TriggerEvent, уменьшает считчик триггера и делает запись в БД. За счет агрегации событий завершения процессов мы уменьшаем нагрузку на БД.
78 1. Когда все дочерние процессы отработали TriggerConsumerRunner получает значение счетчика 0 и взводит триггер.
79 1. Триггер пробуждает родительский процесс для дальнейшего выполнения.
80 )))
81 |(% style="width:870px" %)TriggerEvent публикуются без использования TransactionOutbox напрямую в брокер после коммита транзакции (иначе мы бы нагружали БД).
82 |(% style="width:870px" %)(((
Alexandr Fokin 1.8 83 Предполагаем, что основную часть времени система работает стабильно, но допускается ситуация, что транзакция закоммитилась, но TriggerEvent не смогли опубликоваться (остановка сервиса без graceful shutdown, проблемы соединения или работы с брокером сообщений).
Alexandr Fokin 1.1 84
85 Для таких случаев создается страхующий триггер (1 общий на тип процесса). Этот триггер запускается периодически и проходится по всем ожидающим процессам, проверяя условие (в реализации можно использовать keyset пагинацию) (в реализации можно использовать join для проверки условия).
86 Этот триггер выполняется периодически с более крупной временной задержкой. В случае обнаружения потери TriggerEvent, он поднимет заклинивший родительский процесс и он будет обработан (но позже). Можно установить этому триггеру низкий приоритет.
87 )))
88 )))
89 |(% style="width:32px" %) |(% style="width:171px" %) |(% style="width:1066px" %)
90 )))
91
92