Async functions in Xcode 14.3 are bugged
kelvinlauKL opened this issue ยท 8 comments
Describe the bug
Routes that use async
functions fail to return responses:
import Vapor
@main
public struct Server {
public static func main() async throws {
let app = Application()
app.get("greet") { req in return "Hello" } // <- closure based route handlers work fine
app.get("bye", use: bye) // <- route handlers that uses async functions will not return a response
try app.run()
}
public static func bye(request: Request) async throws -> String {
return "bye"
}
}
// works fine
curl http://127.0.0.1/greet
// never returns any content
curl http://127.0.0.1/bye
To Reproduce
- Create new Swift package named
MyServer
with Xcode 14.3 - Update
Package.swift
to the following:
// swift-tools-version: 5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "MyServer",
platforms: [.macOS(.v13)],
products: [
.executable(
name: "MyServer",
targets: ["MyServer"]),
],
dependencies: [
.package(url: "https://github.com/vapor/vapor.git", .upToNextMajor(from: "4.0.0"))
],
targets: [
.executableTarget(
name: "MyServer",
dependencies: [
.product(name: "Vapor", package: "Vapor")
]),
.testTarget(
name: "MyServerTests",
dependencies: ["MyServer"]),
]
)
- In the auto-created
MyServer.swift
file within Sources/MyServer, add the following code:
import Vapor
@main
public struct Server {
public static func main() async throws {
let app = Application()
app.get("greet") { req in return "Hello" } // <- closure based route handlers work fine
app.get("bye", use: bye) // <- route handlers that uses async functions will not return a response
try app.run()
}
public static func bye(request: Request) async throws -> String {
return "bye"
}
}
- Run the server by hitting CMD+R on Xcode
- Open Terminal and execute the following two commands:
curl http://127.0.0.1:8080/greet
curl http://127.0.0.1:8080/bye
The first curl returns "Hello".
The second curl hangs on Terminal.
- Open up the package and run the server on Xcode 14.2
Running the same two curl commands should work fine.
Environment
- Vapor Framework version: 4.75.0
- Vapor Toolbox version: n/a
- OS version: Ventura 13.3
Additional context
I terminated the second curl by ctrl + c. I then ran lsof -i :8080
which yielded the following output:
MyServer 11081 kelvinlau 14u IPv4 <...> 0t0 TCP localhost:http-alt (LISTEN)
MyServer 11081 kelvinlau 15u IPv4 <...> 0t0 TCP localhost:http-alt->localhost:49323 (CLOSE_WAIT)
If you don't block the main thread inside the @main function by replacing try app.run()
with the following snippet, it will start working even with Xcode 14.3.
try app.start()
try await app.running?.onStop.get()
The problem, most likely, is that your main()
is marked async
. This is a blocking run
function (see #2938).
Note that even if this wasn't causing problems on macOS now, this would've caused you headaches on single-core Linux machines still.
Got it. FYI this code was derived from the 2022 WWDC server side swift video, so I expect others to run into this issue too.
Got it. FYI this code was derived from the 2022 WWDC server side swift video, so I expect others to run into this issue too.
just ran into this issue ๐
See the current template's entrypoint for how to configure it correctly until we add an async version on run()
See the current template's entrypoint for how to configure it correctly until we add an async version on
run()
Thank you. I found a workaround.
Closing this as this is fixed with the new entry point