Отдельный запуск
Клиент запускает операцию и сразу получает номер задачи.
Обезличенный производственный кейс · C++
Подсистема отделяет длительные операции от клиентского запроса и выполняет их в пуле рабочих потоков.
Контекст
В сервисе появились операции, продолжительность которых не укладывалась в обычный синхронный запрос. Если держать соединение открытым, клиент становится зависим от времени обработки и сетевых ограничений.
Клиент запускает операцию и сразу получает номер задачи.
Состояние можно запросить позже по номеру задачи.
Принятые операции попадают в очередь, откуда их забирает ограниченное число рабочих потоков.
Задача проходит состояния «в очереди», «выполняется» и одно из конечных состояний.
Выполнение
Рабочий поток ждёт на условной переменной, под блокировкой извлекает одну задачу и меняет её состояние. После этого блокировка снимается, и начинается длительная операция. Если выполнять её под тем же mutex, остальные потоки не смогут брать задачи и пул фактически станет однопоточным.
Остановка
Условие ожидания реагирует и на появление задачи, и на запрос остановки. Поток завершает работу, когда остановка уже запрошена, а очередь пуста. Это даёт осторожное поведение: перестать принимать новые задачи, закончить уже принятые и затем дождаться завершения рабочих потоков.
Такая политика остановки восстановлена по устройству синхронизации компонента. На странице не утверждается, что в рабочей системе происходили взаимная блокировка или потеря задач.
Ошибки
В восстановленном варианте каждая операция рассматривается как отдельная единица работы. Исключение перехватывается на границе рабочего потока и переводит задачу в состояние ошибки, после чего поток может продолжить обработку очереди. Номер задачи остаётся единой ссылкой как для успешного, так и для неуспешного завершения.
Оценка рабочих показателей
Исходные замеры не сохранились. Диапазоны ниже — осторожная оценка для очереди в памяти и описанного класса длительных операций, а не результаты проверки производительности.
Ожидаемое время на проверку запроса, помещение задачи в очередь и возврат её номера.
Примерный диапазон, в котором отделение операции от клиентского запроса становится полезным.
Реалистичный размер пула для смешанных вычислительных операций и ввода-вывода; остальные задачи ждут в очереди.
Для операций длительностью в несколько секунд возврат только номера задачи сокращает время запроса примерно на два порядка.
Свободные потоки ждут на условной переменной, поэтому не опрашивают очередь непрерывно и почти не создают нагрузку в простое.
Результат
Компонент дал сервису понятный способ запускать длительную работу, выполнять несколько операций одновременно и отдельно сообщать их состояние.