Просмотр исходного кода

Swift 6.1 (#9907)

* Changes for swift 6.1

Also compile fixes for hummingbird2 postgres

* Remove vapor-sqiftql changes

* Revert postgres, sql-kit and swiftql vapor builds

* newline

* Remove Vapor changes

* Remove more Vapor changes
Adam Fowler 3 месяцев назад
Родитель
Сommit
ea1c76b7fd

+ 1 - 1
frameworks/Swift/hummingbird-core/README.md

@@ -9,7 +9,7 @@ Hummingbird Core is the HTTP server for the Hummingbird framework.
 
 ## Important Libraries
 This version of Hummingbird requires
-* [Swift 5.7](https://swift.org)  
+* [Swift 5.10](https://swift.org)  
 * [SwiftNIO 2.x](https://github.com/apple/swift-nio/)
 
 ## Test URLs

+ 2 - 2
frameworks/Swift/hummingbird-core/hummingbird-core.dockerfile

@@ -1,7 +1,7 @@
 # ================================
 # Build image
 # ================================
-FROM swift:5.10 as build
+FROM swift:6.1 AS build
 WORKDIR /build
 
 # Copy entire repo into container
@@ -15,7 +15,7 @@ RUN swift build \
 # ================================
 # Run image
 # ================================
-FROM swift:5.10-slim
+FROM swift:6.1-slim
 WORKDIR /run
 
 # Copy build artifacts

+ 1 - 1
frameworks/Swift/hummingbird/README.md

@@ -13,7 +13,7 @@ Hummingbird is a lightweight, flexible HTTP server framework written in Swift.
 
 ## Important Libraries
 This version of Hummingbird requires
-* [Swift 5.7](https://swift.org)  
+* [Swift 5.10](https://swift.org)  
 * [SwiftNIO 2.x](https://github.com/apple/swift-nio/)
 In these tests for database access it uses
 * [PostgresKit 2.0](https://github.com/vapor/postgres-kit/)

+ 2 - 2
frameworks/Swift/hummingbird/hummingbird-postgres.dockerfile

@@ -1,7 +1,7 @@
 # ================================
 # Build image
 # ================================
-FROM swift:5.10 as build
+FROM swift:6.1 AS build
 WORKDIR /build
 
 # Copy entire repo into container
@@ -15,7 +15,7 @@ RUN swift build \
 # ================================
 # Run image
 # ================================
-FROM swift:5.10-slim
+FROM swift:6.1-slim
 WORKDIR /run
 
 # Copy build artifacts

+ 2 - 2
frameworks/Swift/hummingbird/hummingbird.dockerfile

@@ -1,7 +1,7 @@
 # ================================
 # Build image
 # ================================
-FROM swift:5.10 as build
+FROM swift:6.1 AS build
 WORKDIR /build
 
 # Copy entire repo into container
@@ -15,7 +15,7 @@ RUN swift build \
 # ================================
 # Run image
 # ================================
-FROM swift:5.10-slim
+FROM swift:6.1-slim
 WORKDIR /run
 
 # Copy build artifacts

+ 2 - 2
frameworks/Swift/hummingbird2/hummingbird2-postgres.dockerfile

@@ -1,7 +1,7 @@
 # ================================
 # Build image
 # ================================
-FROM swift:5.10 as build
+FROM swift:6.1 AS build
 WORKDIR /build
 
 # Copy entire repo into container
@@ -15,7 +15,7 @@ RUN swift build \
 # ================================
 # Run image
 # ================================
-FROM swift:5.10-slim
+FROM swift:6.1-slim
 WORKDIR /run
 
 # Copy build artifacts

+ 2 - 2
frameworks/Swift/hummingbird2/hummingbird2.dockerfile

@@ -1,7 +1,7 @@
 # ================================
 # Build image
 # ================================
-FROM swift:5.10 as build
+FROM swift:6.1 AS build
 WORKDIR /build
 
 # Copy entire repo into container
@@ -15,7 +15,7 @@ RUN swift build \
 # ================================
 # Run image
 # ================================
-FROM swift:5.10-slim
+FROM swift:6.1-slim
 WORKDIR /run
 
 # Copy build artifacts

+ 6 - 8
frameworks/Swift/hummingbird2/src-postgres/Package.swift

@@ -1,4 +1,4 @@
-// swift-tools-version:5.10
+// swift-tools-version:6.1
 // The swift-tools-version declares the minimum version of Swift required to build this package.
 
 import PackageDescription
@@ -6,16 +6,14 @@ import PackageDescription
 let package = Package(
     name: "server",
     platforms: [.macOS(.v14)],
-    products: [
-        .executable(name: "server", targets: ["server"])
-    ],
     dependencies: [
-        .package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0-beta.4"),
-        .package(url: "https://github.com/hummingbird-project/swift-mustache.git", from: "2.0.0-beta"),
+        .package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0"),
+        .package(url: "https://github.com/hummingbird-project/swift-mustache.git", from: "2.0.0"),
         .package(url: "https://github.com/vapor/postgres-nio.git", from: "1.21.0"),
     ],
     targets: [
-        .executableTarget(name: "server",
+        .executableTarget(
+            name: "server",
             dependencies: [
                 .product(name: "Hummingbird", package: "hummingbird"),
                 .product(name: "Mustache", package: "swift-mustache"),
@@ -27,6 +25,6 @@ let package = Package(
                 // builds. See <https://github.com/swift-server/guides#building-for-production> for details.
                 .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
             ]
-        ),
+        )
     ]
 )

+ 15 - 13
frameworks/Swift/hummingbird2/src-postgres/Sources/server/Controllers/FortunesController.swift

@@ -5,8 +5,9 @@ import PostgresNIO
 struct HTML: ResponseGenerator, Sendable {
     let html: String
     public func response(from request: Request, context: some RequestContext) -> Response {
-        let buffer = context.allocator.buffer(string: html)
-        return Response(status: .ok, headers: [.contentType: "text/html; charset=utf-8"], body: .init(byteBuffer: buffer))
+        return Response(
+            status: .ok, headers: [.contentType: "text/html; charset=utf-8"],
+            body: .init(byteBuffer: .init(string: html)))
     }
 }
 
@@ -17,9 +18,10 @@ final class FortunesController: Sendable {
 
     init(postgresClient: PostgresClient) {
         self.postgresClient = postgresClient
-        self.template = try! MustacheTemplate(string: """
-        <!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>{{#.}}<tr><td>{{id}}</td><td>{{message}}</td></tr>{{/.}}</table></body></html>
-        """)
+        self.template = try! MustacheTemplate(
+            string: """
+                <!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>{{#.}}<tr><td>{{id}}</td><td>{{message}}</td></tr>{{/.}}</table></body></html>
+                """)
     }
 
     var routes: RouteCollection<Context> {
@@ -28,11 +30,11 @@ final class FortunesController: Sendable {
     }
 
     /// In this test, the framework's ORM is used to fetch all rows from a database
-    ///  table containing an unknown number of Unix fortune cookie messages (the 
-    /// table has 12 rows, but the code cannot have foreknowledge of the table's 
-    /// size). An additional fortune cookie message is inserted into the list at 
-    /// runtime and then the list is sorted by the message text. Finally, the list 
-    /// is delivered to the client using a server-side HTML template. The message 
+    ///  table containing an unknown number of Unix fortune cookie messages (the
+    /// table has 12 rows, but the code cannot have foreknowledge of the table's
+    /// size). An additional fortune cookie message is inserted into the list at
+    /// runtime and then the list is sorted by the message text. Finally, the list
+    /// is delivered to the client using a server-side HTML template. The message
     /// text must be considered untrusted and properly escaped and the UTF-8 fortune messages must be rendered properly.
     @Sendable func fortunes(request: Request, context: Context) async throws -> HTML {
         let rows = try await self.postgresClient.execute(SelectFortuneStatement())
@@ -43,14 +45,14 @@ final class FortunesController: Sendable {
 
         fortunes.append(.init(id: 0, message: "Additional fortune added at request time."))
         let sortedFortunes = fortunes.sorted { $0.message < $1.message }
-        return HTML(html: self.template.render(sortedFortunes) )
-        
+        return HTML(html: self.template.render(sortedFortunes))
+
     }
 
     struct SelectFortuneStatement: PostgresPreparedStatement {
         typealias Row = (Int32, String)
 
-        static var sql = "SELECT id, message FROM Fortune"
+        static let sql = "SELECT id, message FROM Fortune"
 
         func makeBindings() throws -> PostgresNIO.PostgresBindings {
             return .init()

+ 24 - 20
frameworks/Swift/hummingbird2/src-postgres/Sources/server/Controllers/WorldController.swift

@@ -12,20 +12,20 @@ struct WorldController {
             .get("updates", use: updates)
     }
 
-    /// In this test, each request is processed by fetching a single row from a 
+    /// In this test, each request is processed by fetching a single row from a
     /// simple database table. That row is then serialized as a JSON response.
     @Sendable func single(request: Request, context: Context) async throws -> World {
         let id = Int32.random(in: 1...10_000)
         let rows = try await self.postgresClient.execute(SelectWorldStatement(id: id))
-        guard let row = try await rows.first(where: {_ in true }) else {
+        guard let row = try await rows.first(where: { _ in true }) else {
             throw HTTPError(.notFound)
         }
         return World(id: row.0, randomNumber: row.1)
     }
 
-    /// In this test, each request is processed by fetching multiple rows from a 
-    /// simple database table and serializing these rows as a JSON response. The 
-    /// test is run multiple times: testing 1, 5, 10, 15, and 20 queries per request. 
+    /// In this test, each request is processed by fetching multiple rows from a
+    /// simple database table and serializing these rows as a JSON response. The
+    /// test is run multiple times: testing 1, 5, 10, 15, and 20 queries per request.
     /// All tests are run at 512 concurrency.
     @Sendable func multiple(request: Request, context: Context) async throws -> [World] {
         let queries = (request.uri.queryParameters.get("queries", as: Int.self) ?? 1).bound(1, 500)
@@ -34,23 +34,24 @@ struct WorldController {
             result.reserveCapacity(queries)
             for _ in 0..<queries {
                 let id = Int32.random(in: 1...10_000)
-                let rows = try await conn.execute(SelectWorldStatement(id: id), logger: context.logger)
-                guard let row = try await rows.first(where: {_ in true }) else {
+                let rows = try await conn.execute(
+                    SelectWorldStatement(id: id), logger: context.logger)
+                guard let row = try await rows.first(where: { _ in true }) else {
                     throw HTTPError(.notFound)
                 }
-                result.append( World(id: row.0, randomNumber: row.1))
+                result.append(World(id: row.0, randomNumber: row.1))
             }
             return result
         }
     }
 
-    /// This test exercises database writes. Each request is processed by fetching 
-    /// multiple rows from a simple database table, converting the rows to in-memory 
-    /// objects, modifying one attribute of each object in memory, updating each 
-    /// associated row in the database individually, and then serializing the list 
-    /// of objects as a JSON response. The test is run multiple times: testing 1, 5, 
-    /// 10, 15, and 20 updates per request. Note that the number of statements per 
-    /// request is twice the number of updates since each update is paired with one 
+    /// This test exercises database writes. Each request is processed by fetching
+    /// multiple rows from a simple database table, converting the rows to in-memory
+    /// objects, modifying one attribute of each object in memory, updating each
+    /// associated row in the database individually, and then serializing the list
+    /// of objects as a JSON response. The test is run multiple times: testing 1, 5,
+    /// 10, 15, and 20 updates per request. Note that the number of statements per
+    /// request is twice the number of updates since each update is paired with one
     /// query to fetch the object. All tests are run at 512 concurrency.
     @Sendable func updates(request: Request, context: Context) async throws -> [World] {
         let queries = (request.uri.queryParameters.get("queries", as: Int.self) ?? 1).bound(1, 500)
@@ -59,12 +60,15 @@ struct WorldController {
             result.reserveCapacity(queries)
             for _ in 0..<queries {
                 let id = Int32.random(in: 1...10_000)
-                let rows = try await conn.execute(SelectWorldStatement(id: id), logger: context.logger)
-                guard let row = try await rows.first(where: {_ in true }) else {
+                let rows = try await conn.execute(
+                    SelectWorldStatement(id: id), logger: context.logger)
+                guard let row = try await rows.first(where: { _ in true }) else {
                     throw HTTPError(.notFound)
                 }
                 let randomNumber = Int32.random(in: 1...10_000)
-                _ = try await conn.execute(UpdateWorldStatement(id: id, randomNumber: randomNumber), logger: context.logger)
+                _ = try await conn.execute(
+                    UpdateWorldStatement(id: id, randomNumber: randomNumber), logger: context.logger
+                )
                 result.append(World(id: row.0, randomNumber: randomNumber))
             }
             return result
@@ -76,7 +80,7 @@ struct WorldController {
 
         let id: Int32
 
-        static var sql = "SELECT id, randomnumber FROM World WHERE id = $1"
+        static let sql = "SELECT id, randomnumber FROM World WHERE id = $1"
 
         func makeBindings() throws -> PostgresNIO.PostgresBindings {
             var bindings = PostgresNIO.PostgresBindings(capacity: 1)
@@ -93,7 +97,7 @@ struct WorldController {
         let id: Int32
         let randomNumber: Int32
 
-        static var sql = "UPDATE World SET randomnumber = $2 WHERE id = $1"
+        static let sql = "UPDATE World SET randomnumber = $2 WHERE id = $1"
 
         func makeBindings() throws -> PostgresNIO.PostgresBindings {
             var bindings = PostgresNIO.PostgresBindings(capacity: 2)

+ 7 - 21
frameworks/Swift/hummingbird2/src-postgres/Sources/server/main.swift

@@ -13,24 +13,10 @@ extension Int {
 }
 
 struct TechFrameworkRequestContext: RequestContext {
-    static let jsonEncoder = JSONEncoder()
-    static let jsonDecoder = JSONDecoder()
-
-    var coreContext: Hummingbird.CoreRequestContextStorage
-
-    // Use a global JSON Encoder
-    var responseEncoder: JSONEncoder { Self.jsonEncoder }
-    // Use a global JSON Decoder
-    var requestDecoder: JSONDecoder { Self.jsonDecoder }
+    var coreContext: CoreRequestContextStorage
 
     init(source: ApplicationRequestContextSource) {
-        self.init(channel: source.channel, logger: source.logger)
-    }
-
-    init(channel: any Channel, logger: Logger) {
-        self.coreContext = CoreRequestContextStorage(
-            source: ApplicationRequestContextSource(channel: channel, logger: logger)
-        )
+        self.coreContext = CoreRequestContextStorage(source: source)
     }
 }
 
@@ -40,15 +26,15 @@ func runApp() async throws {
     let serverPort = env.get("SERVER_PORT", as: Int.self) ?? 8080
 
     var postgresConfiguration = PostgresClient.Configuration(
-        host: "tfb-database", 
-        username: "benchmarkdbuser", 
-        password: "benchmarkdbpass", 
-        database: "hello_world", 
+        host: "tfb-database",
+        username: "benchmarkdbuser",
+        password: "benchmarkdbpass",
+        database: "hello_world",
         tls: .disable
     )
     postgresConfiguration.options.maximumConnections = 100
     let postgresClient = PostgresClient(
-        configuration: postgresConfiguration, 
+        configuration: postgresConfiguration,
         eventLoopGroup: MultiThreadedEventLoopGroup.singleton
     )
     let router = Router(context: TechFrameworkRequestContext.self)

+ 6 - 8
frameworks/Swift/hummingbird2/src/Package.swift

@@ -1,4 +1,4 @@
-// swift-tools-version:5.10
+// swift-tools-version:6.1
 // The swift-tools-version declares the minimum version of Swift required to build this package.
 
 import PackageDescription
@@ -6,16 +6,14 @@ import PackageDescription
 let package = Package(
     name: "server",
     platforms: [.macOS(.v14)],
-    products: [
-        .executable(name: "server", targets: ["server"])
-    ],
     dependencies: [
-        .package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0-beta"),
+        .package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0")
     ],
     targets: [
-        .target(name: "server",
+        .executableTarget(
+            name: "server",
             dependencies: [
-                .product(name: "Hummingbird", package: "hummingbird"),
+                .product(name: "Hummingbird", package: "hummingbird")
             ],
             swiftSettings: [
                 // Enable better optimizations when building in Release configuration. Despite the use of
@@ -23,6 +21,6 @@ let package = Package(
                 // builds. See <https://github.com/swift-server/guides#building-for-production> for details.
                 .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
             ]
-        ),
+        )
     ]
 )

+ 5 - 18
frameworks/Swift/hummingbird2/src/Sources/server/main.swift

@@ -9,23 +9,10 @@ struct Object: ResponseEncodable {
 }
 
 struct TechFrameworkRequestContext: RequestContext {
+    var coreContext: CoreRequestContextStorage
 
-    static let jsonEncoder = JSONEncoder()
-    static let jsonDecoder = JSONDecoder()
-
-    var coreContext: Hummingbird.CoreRequestContextStorage
-
-    // Use a global JSON Encoder
-    var responseEncoder: JSONEncoder { Self.jsonEncoder }
-    // Use a global JSON Decoder
-    var requestDecoder: JSONDecoder { Self.jsonDecoder }
-
-    init(source: Hummingbird.ApplicationRequestContextSource) {
-        self.coreContext = CoreRequestContextStorage(source: ApplicationRequestContextSource(channel: source.channel, logger: source.logger))
-    }
-
-    init(channel: any Channel, logger: Logger) {
-        self.coreContext = CoreRequestContextStorage(source: ApplicationRequestContextSource(channel: channel, logger: logger))
+    init(source: ApplicationRequestContextSource) {
+        self.coreContext = CoreRequestContextStorage(source: source)
     }
 }
 
@@ -35,10 +22,10 @@ func runApp() async throws {
     let serverPort = env.get("SERVER_PORT", as: Int.self) ?? 8080
 
     let router = Router(context: TechFrameworkRequestContext.self)
-    router.get("plaintext") { _,_ in
+    router.get("plaintext") { _, _ in
         "Hello, world!"
     }
-    router.get("json") { _,_ in
+    router.get("json") { _, _ in
         Object(message: "Hello, world!")
     }
     let app = Application(

+ 2 - 2
frameworks/Swift/swift-nio/swift-nio.dockerfile

@@ -1,7 +1,7 @@
 # ================================
 # Build image
 # ================================
-FROM swift:5.10 as build
+FROM swift:6.1 AS build
 WORKDIR /build
 
 # Copy entire repo into container
@@ -15,7 +15,7 @@ RUN swift build \
 # ================================
 # Run image
 # ================================
-FROM swift:5.10-slim
+FROM swift:6.1-slim
 WORKDIR /run
 
 # Install Swift dependencies