День 1198. #ЧтоНовенького
Обновления ASP.NET Core в .NET 7 Превью 4. Начало
Недавно вышедший превью 4 .NET 7 включает много отличных обновлений в ASP.NET Core.
1. Улучшения производительности HTTP/2
Значительно переработана обработка сервером Kestrel запросов HTTP/2. HTTP/2 позволяет параллельно выполнять до 100 запросов по TCP-соединению. Это называется мультиплексированием. До превью 4 мультиплексирование HTTP/2 в Kestrel основывалось на блокировке через ключевое слово lock для управления тем, какой запрос может записывать в TCP-соединение. Хотя блокировка — это простое решение для написания безопасного многопоточного кода, она неэффективна при высокой конкуренции потоков.
Профилирование и бенчмаркинг Kestrel показывали:
- Высокую конкуренцию за поток, когда соединение занято.
- Пустую трату циклов ЦП из-за запросов, борющихся за блокировку записи.
- Бездействующие ядра ЦП, поскольку запросы ожидали блокировки записи.
- Производительность Kestrel, для других серверов в сценариях с загруженным соединением.
Решение состоит в том, чтобы переписать, как запросы HTTP/2 в Kestrel получают доступ к TCP-соединению. Потокобезопасная очередь заменяет блокировку записи. Вместо того, чтобы бороться за то, кто может использовать блокировку записи, теперь запросы выстраиваются в очередь, и их обрабатывает выделенный потребитель. Ресурсы ЦП, которые ранее тратились впустую, теперь доступны остальной части приложения.
Эти улучшения видны в gRPC, популярной среде RPC, использующей HTTP/2.
2. Типизированные результаты для минимальных API
В .NET 6 представили интерфейс IResult для предоставления значений, возвращаемых из минимальных API, которые не используют неявную поддержку сериализации JSON возвращённого объекта в ответ HTTP. Статический класс Results используется для создания различных объектов IResult, представляющих различные типы ответов, от простой установки кода ответа до перенаправления на другой URL-адрес. Однако типы инфраструктуры, реализующие IResult, возвращаемые этими методами, были внутренними, что затрудняло проверку конкретного типа IResult, возвращаемого методами API, в модульных тестах.
В .NET 7 типы, реализующие IResult в ASP.NET Core, стали общедоступными, что позволяет использовать простые утверждения при тестировании. Пусть у нас есть следующий метод API:
public async Task<IResult> GetTodos(TodoDb db)
{
return Results.Ok(
await db.Todos.ToArrayAsync()
);
}
Тогда проверить результат метода можно следующим образом:
var db = CreateDbContext();
var result = await api.GetTodos(db);
Assert.IsType<Ok<object>>(result);
Обратите внимание, что тип результата — Ok<object>, поскольку метод Results.Ok(object? value = null) принимает значение как объект, а не как исходный тип. Чтобы решить эту проблему, введён новый фабричный класс для создания «типизированных» результатов.
Новый статический класс Microsoft.AspNetCore.Http.TypedResults является «типизированным» эквивалентом существующего класса Microsoft.AspNetCore.Http.Results. Вы можете использовать TypedResults в минимальных API для создания экземпляров типов, реализующих IResult, c сохранением информации о конкретном типе.
Тогда пример выше можно переписать с использованием TypedResults:
public async Task<IResult> GetTodos(TodoDb db)
{
return TypedResults.Ok(
await db.Todos.ToArrayAsync()
);
}
И протестировать уже типизированный результат:
var db = CreateDbContext();
var result = await todosApi.GetTodos(db);
Assert.IsType<Ok<Todo[]>>(result);
Продолжение следует…
Источник: devblogs.microsoft.com/dotnet/…review-4