Aspire 13.6.4 восстанавливает вызовы создания DCP, завершившиеся по таймауту, вместо того чтобы переводить ресурс в состояние сбоя
Aspire 13.6.4 больше не отправляет ресурс в FailedToStart из-за одного вызова создания DCP, завершившегося по таймауту или с HTTP 504, и открывает три таймаута DcpPublisher, которые можно увеличить на медленных CI-раннерах.
Если ваш AppHost на Aspire 13.6 периодически падает на CI, а ресурс застревает в состоянии FailedToStart, вам нужен патч Aspire 13.6.4, выпущенный 2026-10-24. Он меняет то, как AppHost общается с Developer Control Plane (DCP), когда вызов создания не возвращается вовремя, и наконец позволяет настраивать эти таймауты.
Одного медленного вызова создания хватало, чтобы убить ресурс
Начиная с 13.6.0, один запрос Create к API-серверу DCP, завершившийся по таймауту или с HTTP 504, не повторялся. Ресурс сразу переходил в FailedToStart, а все, что делало WaitFor для него, падало с сообщением “Stopped waiting for resource … because it failed to start.” Отчет в microsoft/aspire#20691 пришел с раннеров GitHub macos-15-intel с 2 vCPU, где последний проект в графе стартовал, пока его зависимости еще поднимались. В журналах было либо исключение Polly TimeoutRejectedException после клиентского бюджета в 20 секунд, либо GatewayTimeout от DCP примерно через 34 секунды.
Неприятно то, что таймаут не означает, что создание не удалось. DCP мог зафиксировать объект через мгновение после того, как клиент сдался, поэтому слепой повтор тоже небезопасен.
Сначала проверить, затем повторить для того же объекта
Исправление в #20752 (бэкпорт в #20868) считает создание, завершившееся по таймауту, с кодом 502, 503, 504 или 429, неоднозначным. Перед повтором AppHost выполняет GET для объекта с тем же именем. Если DCP уже создал его, используется этот объект, и ресурс продолжает запускаться. Если GET возвращает 404, создание повторяется с джиттером в задержке, ограниченной 5 секундами. Ответ “already exists” при повторе тоже принимается, так как предыдущая попытка могла дойти уже после проверочного запроса. GET здесь важен, потому что он обходит блокировку публикации API-сервера, за которой мог бы застрять второй POST.
Собственный HttpClientTimeout пакета KubernetesClient в 100 секунд теперь отключен, поэтому он больше не может обрезать настроенный бюджет и проявиться как несвязанная отмена.
Три параметра в DcpPublisher
Теперь эти бюджеты являются обычными параметрами конфигурации AppHost:
| Ключ | По умолчанию | Назначение |
|---|---|---|
DcpPublisher:KubernetesApiTimeout | 40 s | На одну операцию API |
DcpPublisher:KubernetesInitializationAdditionalTimeout | 20 s | Добавляется до первой успешной операции |
DcpPublisher:KubernetesCreateRecoveryTimeout | 2 min | Общий бюджет на восстановление одного создания |
Каждое значение должно быть от одной секунды до десяти минут, а сумма таймаутов API и инициализации не может превышать десять минут, иначе проверка параметров завершится ошибкой при запуске. Уже установленные потоки watch и журналов этим ограничениям не подчиняются.
На слабом раннере увеличьте их в appsettings.json AppHost:
{
"DcpPublisher": {
"KubernetesApiTimeout": "00:01:30",
"KubernetesInitializationAdditionalTimeout": "00:00:45",
"KubernetesCreateRecoveryTimeout": "00:05:00"
}
}
Или оставьте значения репозитория по умолчанию и задайте их только в рабочем процессе CI, поскольку переменные окружения тоже привязываются через IConfiguration:
env:
DcpPublisher__KubernetesApiTimeout: "00:01:30"
DcpPublisher__KubernetesCreateRecoveryTimeout: "00:05:00"
Чтобы обновиться, поднимите версию Aspire.AppHost.Sdk и пакетов Aspire.Hosting.* до 13.6.4. Тот же релиз также ограничивает диагностические журналы CLI в Unix файлами с правами 0600 в каталоге с правами 0700, потому что в этих журналах могут быть URL для входа в панель мониторинга. Если вы догоняете линейку 13.6, статья об истории запусков в панели мониторинга описывает главную возможность того релиза.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.