Skip to content

Commit

Permalink
Avoid an error allocation in the server stream handler (grpc#1970)
Browse files Browse the repository at this point in the history
Motivation:

Existential errors unconditionally allocate. In the server stream
handler a promise is failed on tear down via an API which takes an
existential error. This means the handler always allocates, even if the
promise has been completed.

Modifications:

- Statically allocate the error as an existential

Result:

Fewer allocations
  • Loading branch information
glbrntt committed Jul 5, 2024
1 parent b9b4711 commit 595a416
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions Sources/GRPCHTTP2Core/Server/GRPCServerStreamHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 39,13 @@ final class GRPCServerStreamHandler: ChannelDuplexHandler, RemovableChannelHandl

private let methodDescriptorPromise: EventLoopPromise<MethodDescriptor>

// Existential errors unconditionally allocate, avoid this per-use allocation by doing it
// statically.
private static let handlerRemovedBeforeDescriptorResolved: any Error = RPCError(
code: .unavailable,
message: "RPC stream was closed before we got any Metadata."
)

init(
scheme: GRPCStreamStateMachineConfiguration.Scheme,
acceptedEncodings: CompressionAlgorithmSet,
Expand Down Expand Up @@ -159,12 166,7 @@ extension GRPCServerStreamHandler {

func handlerRemoved(context: ChannelHandlerContext) {
self.stateMachine.tearDown()
self.methodDescriptorPromise.fail(
RPCError(
code: .unavailable,
message: "RPC stream was closed before we got any Metadata."
)
)
self.methodDescriptorPromise.fail(Self.handlerRemovedBeforeDescriptorResolved)
}

func channelInactive(context: ChannelHandlerContext) {
Expand Down

0 comments on commit 595a416

Please sign in to comment.