From 40bd176799d721dd0cebcfda53fa2d3341be977b Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 2 Apr 2022 20:25:25 +0900 Subject: [PATCH] Fix hunged watcher (#307) Actor isolated methods must not block the current thread, so Vapor server's start method is not compatible in Concurrency context. --- Sources/CartonKit/Server/Server.swift | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/Sources/CartonKit/Server/Server.swift b/Sources/CartonKit/Server/Server.swift index d3e34d6..4f68116 100644 --- a/Sources/CartonKit/Server/Server.swift +++ b/Sources/CartonKit/Server/Server.swift @@ -227,9 +227,26 @@ public actor Server { } /// Blocking function that starts the HTTP server. - public func run() throws { - defer { app.shutdown() } - try app.run() + public nonisolated func run() async throws { + // Explicitly hop to another thread to avoid blocking the thread that is running the actor executor + try await withCheckedThrowingContinuation { (continuation: CheckedContinuation) in + Thread { + Task { + do { + defer { self.app.shutdown() } + try self.app.run() + try await self.closeSockets() + continuation.resume() + } catch { + continuation.resume(with: .failure(error)) + } + } + } + .start() + } + } + + func closeSockets() throws { for conn in connections { try conn.close().wait() }