Repository: apple/swift-nio
File: Sources/NIOTCPEchoServer/Server.swift (Swift)

Code before:
    private let host: String
    /// The server's port.
    private let port: Int
    /// The server's event loop group.
    private let eventLoopGroup: MultiThreadedEventLoopGroup

    static func main() async throws {
        let server = Server(
            host: "localhost",
            port: 8765,
            eventLoopGroup: .singleton
        )
        try await server.run()
    }

    /// This method starts the server and handles incoming connections.
    func run() async throws {
        let channel = try await ServerBootstrap(group: eventLoopGroup)
            .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
            .bind(
                host: self.host,
                port: self.port
            ) { channel in
                channel.eventLoop.makeCompletedFuture {
                    // We are using two simple handlers here to frame our messages with "\n"
                    try channel.pipeline.syncOperations.addHandler(ByteToMessageHandler(NewlineDelimiterCoder()))
                    try channel.pipeline.syncOperations.addHandler(MessageToByteHandler(NewlineDelimiterCoder()))

                    return try NIOAsyncChannel(
                        synchronouslyWrapping: channel,
                        configuration: .init(
                            inboundType: String.self,
                            outboundType: String.self
                        )
                    )
                }
            }

        // We are handling each incoming connection in a separate child task. It is important
        // to use a discarding task group here which automatically discards finished child tasks.
        // A normal task group retains all child tasks and their outputs in memory until they are
        // consumed by iterating the group or by exiting the group. Since, we are never consuming
        // the results of the group we need the group to automatically discard them; otherwise, this
        // would result in a memory leak over time.
        try await withThrowingDiscardingTaskGroup { group in
            for try await connectionChannel in channel.inboundStream {
                group.addTask {
                    print("Handling new connection")
                    await self.handleConnection(channel: connectionChannel)
                    print("Done handling connection")
                }

Review comment (bug):
all these `try`s should be `try!`s, they can't fail unless programmer error, right?

Code after:
    private let host: String
    /// The server's port.
    private let port: Int
    /// The server's event loop group.
    private let eventLoopGroup: MultiThreadedEventLoopGroup

    static func main() async throws {
        let server = Server(
            host: "localhost",
            port: 8765,
            eventLoopGroup: .singleton
        )
        try await server.run()
    }

    /// This method starts the server and handles incoming connections.
    func run() async throws {
        let channel = try await ServerBootstrap(group: self.eventLoopGroup)
            .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
            .bind(
                host: self.host,
                port: self.port
            ) { channel in
                channel.eventLoop.makeCompletedFuture {
                    // We are using two simple handlers here to frame our messages with "\n"
                    try channel.pipeline.syncOperations.addHandler(ByteToMessageHandler(NewlineDelimiterCoder()))
                    try channel.pipeline.syncOperations.addHandler(MessageToByteHandler(NewlineDelimiterCoder()))

                    return try NIOAsyncChannel(
                        synchronouslyWrapping: channel,
                        configuration: NIOAsyncChannel.Configuration(
                            inboundType: String.self,
                            outboundType: String.self
                        )
                    )
                }
            }

        // We are handling each incoming connection in a separate child task. It is important
        // to use a discarding task group here which automatically discards finished child tasks.
        // A normal task group retains all child tasks and their outputs in memory until they are
        // consumed by iterating the group or by exiting the group. Since, we are never consuming
        // the results of the group we need the group to automatically discard them; otherwise, this
        // would result in a memory leak over time.
        try await withThrowingDiscardingTaskGroup { group in
            for try await connectionChannel in channel.inboundStream {
                group.addTask {
                    print("Handling new connection")
                    await self.handleConnection(channel: connectionChannel)
                    print("Done handling connection")
                }