Skip to content

Commit

Permalink
Reduce time spent logging EventLoop description in HTTP1ClientChannel…
Browse files Browse the repository at this point in the history
…Handler (#772)

### Motivation:

A performance test executing 100,000 sequential requests against a
simple
[`NIOHTTP1Server`](https://github.com/apple/swift-nio/blob/main/Sources/NIOHTTP1Server/README.md)
revealed that 7% of total run time is spent in the setter of the
`request` property in `HTTP1ClientChannelHandler` (GitHub Issue #754).

The poor performance comes from [processing the string interpolation
`"\(self.eventLoop)"`](https://github.com/swift-server/async-http-client/blob/6df8e1c17e68f0f93de2443b8c8cafca9ddcc89a/Sources/AsyncHTTPClient/ConnectionPool/HTTP1/HTTP1ClientChannelHandler.swift#L39C17-L39C75)
which under the hood calls a computed property.

This problem can entirely be avoided by storing `eventLoop.description`
when initializing `HTTP1ClientChannelHandler`, and using that stored
value in `request`'s setter, rather than computing the property each
time.

### Modifications:

- Created a new property `let eventLoopDescription:
Logger.MetadataValue` in `HTTP1ClientChannelHandler` that stores the
description of the `eventLoop` argument that is passed into the
initializer.
- Replaced the string interpolation `"\(self.eventLoop)"` in `request`'s
setter with `self.eventLoopDescription`.

### Result:

`HTTP1ClientChannelHandler.eventLoop`'s `description` property is cached
upon initialization rather than being computed each time in the
`request` property's setter.

---------

Co-authored-by: Cory Benfield <[email protected]>
  • Loading branch information
aryan-25 and Lukasa authored Sep 23, 2024
1 parent 15dbe6d commit 38608db
Showing 1 changed file with 3 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
if let newRequest = self.request {
var requestLogger = newRequest.logger
requestLogger[metadataKey: "ahc-connection-id"] = self.connectionIdLoggerMetadata
requestLogger[metadataKey: "ahc-el"] = "\(self.eventLoop)"
requestLogger[metadataKey: "ahc-el"] = self.eventLoopDescription
self.logger = requestLogger

if let idleReadTimeout = newRequest.requestOptions.idleReadTimeout {
Expand Down Expand Up @@ -72,11 +72,13 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
private let backgroundLogger: Logger
private var logger: Logger
private let eventLoop: EventLoop
private let eventLoopDescription: Logger.MetadataValue
private let connectionIdLoggerMetadata: Logger.MetadataValue

var onConnectionIdle: () -> Void = {}
init(eventLoop: EventLoop, backgroundLogger: Logger, connectionIdLoggerMetadata: Logger.MetadataValue) {
self.eventLoop = eventLoop
self.eventLoopDescription = "\(eventLoop.description)"
self.backgroundLogger = backgroundLogger
self.logger = backgroundLogger
self.connectionIdLoggerMetadata = connectionIdLoggerMetadata
Expand Down

0 comments on commit 38608db

Please sign in to comment.