Skip to content

Правки работы функции polling#3

Merged
Deskri merged 6 commits intoDeskri:devfrom
JeyDim:fix-polling
Apr 16, 2026
Merged

Правки работы функции polling#3
Deskri merged 6 commits intoDeskri:devfrom
JeyDim:fix-polling

Conversation

@JeyDim
Copy link
Copy Markdown
Contributor

@JeyDim JeyDim commented Apr 16, 2026

Получил неожиданные проблемы при работе с botClient.StartReceiving - фоновое завершение работы бота без выбрасывания какого-либо Exception.

Исправил следующие недачеты которые вроде бы могли привести к данной проблеме:

  • TaskCanceledException (от таймаута HttpClient) наследуется от OperationCanceledException. Без фильтра when polling loop не мог отличить реальную отмену пользователя от HTTP-таймаута и молча завершался в обоих случаях — бот переставал получать сообщения.
  • Если пользовательский errorHandler выбрасывал исключение, оно вылетало из catch-блока и убивало polling loop. Поскольку StartReceiving использует fire-and-forget Task.Run, исключение терялось и бот молча переставал получать сообщения.
  • При сбое API polling loop мгновенно повторял запросы без задержки, создавая tight loop. Теперь между ошибочными итерациями есть пауза 5 секунд, чтобы не забивать API при длительном сбое и дать ему время восстановиться.
  • Дефолтный таймаут HttpClient — 100 секунд, а long polling может держать соединение до 90 секунд. При сетевых задержках HttpClient таймаутился раньше сервера, вызывая TaskCanceledException.
  • Раньше Task.Run был fire-and-forget — если ReceiveAsync падал, исключение терялось и вызывающий код не мог узнать о проблеме.

@Deskri Deskri merged commit 469255d into Deskri:dev Apr 16, 2026
@JeyDim JeyDim deleted the fix-polling branch April 16, 2026 12:31
Deskri added a commit that referenced this pull request Apr 16, 2026
* feat: init project

* feat: add api methods params

* feat: add tests

* feat: update readme

* feat: add version and update System.Text.Json

(cherry picked from commit 0b563a3e2d0fb7cc5d6c371a237a424d95825c0a)

* fix: deserialize dtos

(cherry picked from commit d62a02073f75e8507d571347f39735b795915c37)

* fix: chat type

(cherry picked from commit e3b9bba727ff2616257766f5dc1bce764b562c00)

* fix: chat type of bot in api methods

(cherry picked from commit 97b457ab009ba4dc68154f4135fe0820a7a72a36)

* feat: update .csproj

* feat: start 1.0.1 version

* feat: add package project url

* feat: add DI support for .NET 10

Register IBotClient via AddMaxBotClient() extension on IServiceCollection.
Uses IHttpClientFactory and conditional compilation (#if NET10_0_OR_GREATER).
DI packages referenced only for net10.0 target.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: add GitHub Actions workflow for NuGet publish

Publishes package to NuGet on every push to main.
Requires NUGET_API_KEY secret in repository settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: add test step before publish

Run xUnit tests on net8.0 before building and packing.
Publish is blocked if tests fail.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: upgrade test project to net10.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: split build/test and publish into separate jobs

- build-and-test runs on push to main and dev
- publish runs only on main, requires build-and-test to pass
- publish uses 'main' environment for NUGET_API_KEY secret

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add dedicated polling HttpClient with infinite timeout for long polling

Separate HttpClient with Timeout.InfiniteTimeSpan prevents TaskCanceledException
during long polling when server holds connection up to 90 seconds.

- Add internal IBotClientInternal interface with PollingSendRequest (explicit impl)
- Add PollingProcessApi/GetUpdatesFromPolling parallel to existing ProcessApi/GetUpdates
- Lazy-create polling HttpClient on first use
- Implement IDisposable with _ownsHttpClient tracking for safe cleanup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Правки работы функции polling (#3)

* fix: различаем отмену пользователя и HTTP-таймаут в polling loop

* fix: защита errorHandler от выброса исключений в polling loop

* fix: добавлен backoff (5 сек) между ошибками в polling loop

* fix: установлен бесконечный таймаут HttpClient для long polling

* fix: StartReceiving возвращает Task вместо void

* fix: не переопределяем глобальный Timeout

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Sergey Novik <Sergeynovik73@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants