gRPC Support
Failsafe-go makes it easy to use any policies with gRPC.
Clients
You can create a failsafe UnaryClientInterceptor
for a policy composition to handle errors, limit load, or limit execution time:
interceptor := failsafegrpc.NewUnaryClientInterceptor[SomeResponse](retryPolicy, circuitBreaker)
client, err := grpc.NewClient(target, grpc.WithUnaryInterceptor(interceptor))
// Perform an RPC with retries and circuit breaking
service := somepkg.NewSomeServiceClient(client)
service.DoSomething(ctx, request)
Servers
On the server side, you can use load limiting or time limiting policies to create a failsafe ServerInHandle
:
inTapHandle := failsafegrpc.NewServerInHandle[any](bulkhead, timeout)
server := grpc.NewServer(grpc.InTapHandle(inTapHandle))
You can also create a failsafe UnaryServerInterceptor
:
interceptor := failsafegrpc.NewUnaryServerInterceptor[SomeResponse](retryPolicy, circuitBreaker)
server := grpc.NewServer(target, grpc.UnaryInterceptor(interceptor))
The difference between these two approaches is that a ServerInHandle
handles a request before it has been decoded whereas a UnaryServerInterceptor
allows your policies to handle the contents of a response.
For most load limiting use cases, prefer ServerInHandle
since it does not create additional server side resources for requests that are rejected. For use cases where a policy needs to inspect the response, such as a Fallback
or a CircuitBreaker
, you can use a UnaryServerInterceptor
.
Fallbacks
When using a Fallback with a UnaryClientInterceptor
, it’s necessary to set your fallback value against the execution’s LastResult()
since a UnaryClientInterceptor has no way to return an alternative result:
fb := fallback.WithFunc(func(exec failsafe.Execution[*SomeResponse]) (*SomeResponse, error) {
exec.LastResult().Msg = "fallback"
return nil, nil
})
A Fallback with a UnaryServerInterceptor
can be used as usual since UnaryServerInterceptor does allow an alternative result to be returned:
fb := fallback.WithResult(&SomeResponse{Msg: "fallback"})
Context Cancellation
When using Failsafe-go’s gRPC support, Context cancellations are automatically propagated to the RPC context. When an execution is canceled for any reason, such as a Timeout, any outstanding RPC’s context is canceled. Similarly, when using a HedgePolicy, any outstanding hedge RPC contexts are canceled once the first successful response is received.