Upgrade/12 channels - #69
Merged
Merged
Conversation
BackgroundTaskQueue поверх ограниченного Channel плюс BackgroundTaskProcessor как BackgroundService. Отличия от прежнего fire-and-forget: - очередь ограничена (1000), переполнение не блокирует поток запроса, а отбрасывает работу с предупреждением в лог - параллелизм обработчика ограничен четырьмя работами - при остановке приложения очередь закрывается на запись, а уже принятые работы дочитываются и выполняются, а не теряются вместе с процессом Вызовы Forget() пока не тронуты — переключение отдельным коммитом.
Две проблемы обработчика, найденные замерами. Первая — потеря работ при остановке. BackgroundService запускает ExecuteAsync отложенно: если приложение останавливается вскоре после старта, задача отменяется до входа в тело метода, и очередь никто не разбирает. Из 300 прогонов падало 263. Разбор вынесен в отдельный метод, который вызывается и из ExecuteAsync, и из StopAsync после базовой остановки — стало 0 из 300. Вторая — потеря параллельности. Прежний fire-and-forget выполнял работы одновременно, и медленная не задерживала остальные. Очередь с одним потребителем это ломала: работа, поставленная за вызовом Dialogflow, ждала его 200 мс. Теперь канал читают несколько независимых потребителей, их число ограничено четырьмя. Замер после правки: 0 мс. Parallel.ForEachAsync для этого не подходит: при остановке его задача завершается как отменённая, не дочитав очередь. Добавлен тест-сторож на параллельность: при одном потребителе он краснеет.
Три места, где результат намеренно не дожидались, переведены с TasksExtensions.Forget() на IBackgroundTaskQueue: - ConversationService — установка контекста savedText - SberService — запись идентификатора сессии в Redis - MarusiaService — отметка о пользователе в Redis TasksExtensions удалён. Прежний Forget() запускал задачу без ограничений по количеству и терял её при остановке процесса; теперь работы идут через ограниченную очередь и дочитываются при штатной остановке. Постановка в очередь не блокирует поток запроса вообще — это запись в канал. Forget() был чуть хуже: асинхронный метод стартовал синхронно на потоке запроса до первого await. В тестах подменена сама очередь: она выполняет работу сразу, поэтому ожидание с опросом больше не нужно. Проверки остались прежними — SetContextAsync и AddAsync вызываются с теми же аргументами.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.