Files
Deal/src/ai-service/Deal.Ai/AiServiceHost.cs
T
Rustam Khalimov b053d58335 Почистить комментарии от упоминаний процесса
Удалены <remarks>, <summary> сжаты до короткой фразы, вырезаны
ссылки на Task/Ruling/этап/python/прототип; //-комментарии со ссылками
на процесс удалены; то же в .proto. Правила обновлены в
docs/spec/Код-стайл-Дейл.md. Строк комментариев 27210 -> ~19100.
2026-09-11 13:39:39 +03:00

62 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Deal.Grpc.Hosting.Interceptors;
using Deal.Grpc.Hosting.Models;
using Deal.Grpc.Hosting.Options;
using Deal.Grpc.Hosting.Services;
namespace Deal.Ai;
/// <summary>
/// Собирает WebApplication gRPC-хоста ai-service.
/// </summary>
public static class AiServiceHost
{
/// <summary>
/// Создаёт (не запускает) хост
/// </summary>
/// <param name="grpcPort">TCP-порт Kestrel.</param>
/// <param name="args">Аргументы командной строки (Program.cs); в тестах не нужны.</param>
/// <param name="configureServices">Опциональный хук DI для тестов (подмена LLM-фасада фейками: регистрация, добавленная здесь, побеждает — DI резолвит последнюю; см. AiServiceHostTests/AiRpcTests).</param>
/// <param name="configureBuilder">Опциональный хук конфигурации билдера для production-точки входа (Program.cs): Serilog. Тесты хост поднимают БЕЗ этого хука — логирование файлов/консоли тестам не нужно.</param>
/// <returns>Собранный хост; запуск — StartAsync/RunAsync у вызывающего.</returns>
public static WebApplication Create(
int grpcPort,
string[]? args = null,
Action<IServiceCollection>? configureServices = null,
Action<WebApplicationBuilder>? configureBuilder = null)
{
WebApplicationBuilder builder = WebApplication.CreateBuilder(args ?? []);
// Общая серверная обвязка (Deal.Grpc.Hosting, C31): mTLS env DEAL_MTLS_* — загрузка
// сертификатов сразу с fail-fast (compose-prod монтирует deploy/certs, scripts/mtls-certs.sh);
MtlsCertificates? mtlsCertificates = GrpcServer.LoadMtlsCertificates(builder);
GrpcServer.ConfigureKestrelHttp2Endpoint(builder, grpcPort, mtlsCertificates);
builder.Services.AddDealGrpcServer();
builder.Services.AddReadyHealthCheck("хост ai-service готов");
// попытки управляется внутри — 90 с OpenAI / 60 с Anthropic; клиент без общего таймаута) и
// оркестратор ретраев/JSON/usage поверх него. Ключи API — в конфиге запроса, не в DI/логах.
builder.Services.AddHttpClient<Llm.LlmHttpClient>(static httpClient =>
httpClient.Timeout = Timeout.InfiniteTimeSpan);
builder.Services.AddSingleton<Llm.IProviderClient>(
static sp => sp.GetRequiredService<Llm.LlmHttpClient>());
builder.Services.AddSingleton<Func<TimeSpan, CancellationToken, Task>>(DefaultRetryDelayAsync);
builder.Services.AddSingleton<Llm.ProviderCaller>();
configureServices?.Invoke(builder.Services);
configureBuilder?.Invoke(builder);
WebApplication app = builder.Build();
app.MapGrpcService<AiServiceImpl>();
app.MapGrpcHealthChecksService();
return app;
}
// Пауза между ретраями по умолчанию (Task.Delay; тесты подменяют через DI).
// delay: Длительность паузы.
// cancellationToken: Токен отмены.
private static Task DefaultRetryDelayAsync(TimeSpan delay, CancellationToken cancellationToken)
=> Task.Delay(delay, cancellationToken);
}