Skip to content

Commit

Permalink
Use NIO defaults for maxMessagesPerRead unless overridden
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler committed May 8, 2024
1 parent 097a686 commit fd0ccc5
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 26 deletions.
19 changes: 10 additions & 9 deletions Sources/Hummingbird/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ public struct ApplicationConfiguration: Sendable {
/// Defines the maximum length for the queue of pending connections
public var backlog: Int
/// This will affect how many connections the server accepts at any one time
public let serverMaxMessagesPerRead: UInt
public var serverMaxMessagesPerRead: UInt?
/// This will affect how much is read from a connection at any one time
public let childMaxMessagesPerRead: UInt
public var childMaxMessagesPerRead: UInt?
/// Allows socket to be bound to an address that is already in use.
public var reuseAddress: Bool
#if canImport(Network)
Expand All @@ -52,15 +52,16 @@ public struct ApplicationConfiguration: Sendable {
/// - backlog: the maximum length for the queue of pending connections. If a connection request arrives with the queue full,
/// the client may receive an error with an indication of ECONNREFUSE
/// - serverMaxMessagesPerRead: This will affect how many connections the server accepts before waiting for notification of
/// more. Setting this too high can flood the server with too much work.
/// - childMaxMessagesPerRead: This will affect how much is read from a connection before waiting for notification of more
/// - reuseAddress: Allows socket to be bound to an address that is already in use.
/// more. Setting this too high can flood the server with too much work. DO NOT EDIT this unless you know what you are doing
/// - childMaxMessagesPerRead: This will affect how much is read from a connection before waiting for notification of more. DO
/// NOT EDIT this unless you know what you are doing
/// - reuseAddress: Allows socket to be bound to an address that is already in use.
public init(
address: Address = .hostname(),
serverName: String? = nil,
backlog: Int = 256,
serverMaxMessagesPerRead: UInt = 8,
childMaxMessagesPerRead: UInt = 1,
serverMaxMessagesPerRead: UInt? = nil,
childMaxMessagesPerRead: UInt? = nil,
reuseAddress: Bool = true
) {
self.address = address
Expand Down Expand Up @@ -94,8 +95,8 @@ public struct ApplicationConfiguration: Sendable {
self.tlsOptions = tlsOptions
// The following are not used by Network framework
self.backlog = 256
self.serverMaxMessagesPerRead = 8
self.childMaxMessagesPerRead = 1
self.serverMaxMessagesPerRead = nil
self.childMaxMessagesPerRead = nil
}

#endif
Expand Down
11 changes: 8 additions & 3 deletions Sources/HummingbirdCore/Server/Server.swift
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,19 @@ public actor Server<ChildChannel: ServerChildChannel>: Service {
private nonisolated func createSocketsBootstrap(
configuration: ServerConfiguration
) -> ServerBootstrap {
return ServerBootstrap(group: self.eventLoopGroup)
var bootstrap = ServerBootstrap(group: self.eventLoopGroup)
// Specify backlog and enable SO_REUSEADDR for the server itself
.serverChannelOption(ChannelOptions.backlog, value: numericCast(configuration.backlog))
.serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: configuration.reuseAddress ? 1 : 0)
.serverChannelOption(ChannelOptions.maxMessagesPerRead, value: configuration.serverMaxMessagesPerRead)
.childChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: configuration.reuseAddress ? 1 : 0)
.childChannelOption(ChannelOptions.maxMessagesPerRead, value: configuration.childMaxMessagesPerRead)
.childChannelOption(ChannelOptions.allowRemoteHalfClosure, value: true)
if let serverMaxMessagesPerRead = configuration.serverMaxMessagesPerRead {
bootstrap = bootstrap.serverChannelOption(ChannelOptions.maxMessagesPerRead, value: serverMaxMessagesPerRead)
}
if let childMaxMessagesPerRead = configuration.childMaxMessagesPerRead {
bootstrap = bootstrap.serverChannelOption(ChannelOptions.maxMessagesPerRead, value: childMaxMessagesPerRead)
}
return bootstrap
}

#if canImport(Network)
Expand Down
29 changes: 15 additions & 14 deletions Sources/HummingbirdCore/Server/ServerConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ import NIOCore
/// HTTP server configuration
public struct ServerConfiguration: Sendable {
/// Bind address for server
public let address: Address
public var address: Address
/// Server name to return in "server" header
public let serverName: String?
public var serverName: String?
/// Defines the maximum length for the queue of pending connections
public let backlog: Int
public var backlog: Int
/// This will affect how many connections the server accepts at any one time
public let serverMaxMessagesPerRead: UInt
public var serverMaxMessagesPerRead: UInt?
/// This will affect how much is read from a connection at any one time
public let childMaxMessagesPerRead: UInt
public var childMaxMessagesPerRead: UInt?
/// Allows socket to be bound to an address that is already in use.
public let reuseAddress: Bool
public var reuseAddress: Bool
#if canImport(Network)
/// TLS options for NIO Transport services
public let tlsOptions: TSTLSOptions
public var tlsOptions: TSTLSOptions
#endif

/// Initialize server configuration
Expand All @@ -40,15 +40,16 @@ public struct ServerConfiguration: Sendable {
/// - backlog: the maximum length for the queue of pending connections. If a connection request arrives with the queue full,
/// the client may receive an error with an indication of ECONNREFUSE
/// - serverMaxMessagesPerRead: This will affect how many connections the server accepts before waiting for notification of
/// more. Setting this too high can flood the server with too much work.
/// - childMaxMessagesPerRead: This will affect how much is read from a connection before waiting for notification of more
/// - reuseAddress: Allows socket to be bound to an address that is already in use.
/// more. Setting this too high can flood the server with too much work. DO NOT EDIT this unless you know what you are doing
/// - childMaxMessagesPerRead: This will affect how much is read from a connection before waiting for notification of more. DO NOT
/// EDIT this unless you know what you are doing
/// - reuseAddress: Allows socket to be bound to an address that is already in use.
public init(
address: Address = .hostname(),
serverName: String? = nil,
backlog: Int = 256,
serverMaxMessagesPerRead: UInt = 8,
childMaxMessagesPerRead: UInt = 1,
serverMaxMessagesPerRead: UInt? = nil,
childMaxMessagesPerRead: UInt? = nil,
reuseAddress: Bool = true
) {
self.address = address
Expand Down Expand Up @@ -81,8 +82,8 @@ public struct ServerConfiguration: Sendable {
self.tlsOptions = tlsOptions
// The following are unsupported by transport services
self.backlog = 256
self.serverMaxMessagesPerRead = 8
self.childMaxMessagesPerRead = 1
self.serverMaxMessagesPerRead = nil
self.childMaxMessagesPerRead = nil
}
#endif
}

0 comments on commit fd0ccc5

Please sign in to comment.