Prazos, cancelamento e interceptadores
Aplique timeouts com prazos, propague CancellationToken e adicione preocupações transversais por meio de interceptadores gRPC.
Prazos, cancelamento e interceptadores é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
Confiabilidade no gRPC: prazos e cancelamento
Os serviços gRPC em produção precisam lidar com duas questões essenciais de confiabilidade: prazos (por quanto tempo o cliente aguardará) e cancelamento (interrupção antecipada do trabalho). Juntos, eles evitam o esgotamento de recursos e falhas em cascata.
Definindo um prazo para uma chamada
Um prazo é um instante absoluto até o qual a chamada deve ser concluída. Defina-o com CallOptions. Se ele for ultrapassado, o servidor receberá um cancelamento e o cliente obterá StatusCode.DeadlineExceeded.
var deadline = DateTime.UtcNow.AddSeconds(5);
var reply = await client.GetOrderAsync(
new GetOrderRequest { Id = 42 },
deadline: deadline);
// Or via CallOptions:
var options = new CallOptions(deadline: deadline);
var reply2 = await client.GetOrderAsync(
new GetOrderRequest { Id = 42 }, options);Tratando DeadlineExceeded no cliente
Capture RpcException e verifique o código de status para diferenciar a expiração do prazo de outros erros.
try
{
var reply = await client.GetOrderAsync(
new GetOrderRequest { Id = 42 },
deadline: DateTime.UtcNow.AddSeconds(3));
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.DeadlineExceeded)
{
Console.WriteLine("Call timed out");
}
catch (RpcException ex)
{
Console.WriteLine($"gRPC error: {ex.Status.Detail}");
}Respeitando os prazos no servidor
O servidor deve verificar context.CancellationToken durante trabalhos longos. Quando o prazo expira, esse token é cancelado automaticamente.
public override async Task<ReportResponse> GenerateReport(
ReportRequest request,
ServerCallContext context)
{
var ct = context.CancellationToken;
// Pass ct to every async call — work stops when deadline hits
var data = await _db.FetchLargeDatasetAsync(request.Filters, ct);
var report = await _reportEngine.BuildAsync(data, ct);
ct.ThrowIfCancellationRequested(); // explicit check before CPU work
return MapToResponse(report);
}Propagação de CancellationToken
Sempre propague o token de cancelamento do servidor por toda a cadeia de chamadas assíncronas. Se você ignorá-lo, as chamadas canceladas continuarão consumindo recursos desnecessariamente.
// GOOD: token flows through the call chain
await _db.Products.AsNoTracking()
.Where(p => p.IsActive)
.ToListAsync(context.CancellationToken); // cancels if client disconnects
// BAD: ignores cancellation
await _db.Products.ToListAsync(); // keeps running after deadlineInterceptadores gRPC: conceito
Os interceptadores são o equivalente gRPC dos componentes intermediários do ASP.NET Core: eles são executados antes ou depois das chamadas RPC e podem inspecionar ou modificar solicitações, respostas e exceções. São ideais para registro, autenticação e lógica de repetição.
Criando um interceptador no servidor
Herede de Interceptor e substitua o tipo de método que deseja interceptar. Chame continuation para prosseguir até o manipulador real.
using Grpc.Core.Interceptors;
public class LoggingInterceptor : Interceptor
{
private readonly ILogger<LoggingInterceptor> _logger;
public LoggingInterceptor(ILogger<LoggingInterceptor> l) => _logger = l;
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
_logger.LogInformation("gRPC call: {Method}", context.Method);
var sw = System.Diagnostics.Stopwatch.StartNew();
var response = await continuation(request, context);
_logger.LogInformation("Completed in {Ms}ms", sw.ElapsedMilliseconds);
return response;
}
}Registrando interceptadores no servidor
Registre os interceptadores globalmente (em todos os serviços) ou por serviço em Program.cs. O contêiner de DI resolve as dependências do construtor.
// Globally for all gRPC services:
builder.Services.AddGrpc(opt =>
opt.Interceptors.Add<LoggingInterceptor>());
// Or per service:
builder.Services.AddGrpc();
builder.Services.AddSingleton<LoggingInterceptor>();
app.MapGrpcService<OrderService>()
.AddInterceptor<LoggingInterceptor>();Interceptadores no cliente
Os interceptadores do cliente envolvem as chamadas de saída — são úteis para adicionar cabeçalhos de autenticação, lógica de repetição ou identificadores de correlação sem modificar cada ponto de chamada.
public class AuthInterceptor : Interceptor
{
private readonly ITokenProvider _tokens;
public AuthInterceptor(ITokenProvider t) => _tokens = t;
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
var headers = context.Options.Headers ?? new Metadata();
headers.Add("authorization", $"Bearer {_tokens.GetToken()}");
var newContext = new ClientInterceptorContext<TRequest, TResponse>(
context.Method, context.Host,
context.Options.WithHeaders(headers));
return continuation(request, newContext);
}
}
// Attach to channel:
var invoker = channel.Intercept(new AuthInterceptor(tokenProvider));
var client = new OrderService.OrderServiceClient(invoker);Interceptador de exceções
Um interceptador de exceções no servidor converte exceções não tratadas em RpcExceptions, impedindo que detalhes internos sejam expostos aos clientes.
public class ExceptionInterceptor : Interceptor
{
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
try
{
return await continuation(request, context);
}
catch (NotFoundException ex)
{
throw new RpcException(new Status(StatusCode.NotFound, ex.Message));
}
catch (Exception ex)
{
throw new RpcException(new Status(StatusCode.Internal, "Internal error"));
}
}
}Verificação rápida
O que acontece quando uma chamada gRPC ultrapassa o prazo?
Recapitulação: prazos, cancelamento e interceptadores
Principais conclusões:
- Sempre defina prazos nas chamadas do cliente para evitar esperas sem limite
- Verifique
context.CancellationTokenno servidor e passe-o para todas as chamadas assíncronas - Os interceptadores tratam questões transversais (registro, autenticação e mapeamento de erros) sem poluir o código do serviço
- Interceptadores do servidor: substitua os métodos de tratamento Unary/Stream e chame
continuation - Interceptadores do cliente: associe-os à cadeia de invocadores do canal
Perguntas Frequentes
A aula “Prazos, cancelamento e interceptadores” é grátis?
Sim — o texto completo de “Prazos, cancelamento e interceptadores” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “Prazos, cancelamento e interceptadores”?
Aplique timeouts com prazos, propague CancellationToken e adicione preocupações transversais por meio de interceptadores gRPC. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Prazos, cancelamento e interceptadores”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Fundamentos de gRPC e Protobuf
- RPCs unários e transmissão pelo servidor
- Transmissão pelo cliente e bidirecional
- Prazos, cancelamento e interceptadores