From 25d29f5b0734a375632618f48a3cc5c41d4f244f Mon Sep 17 00:00:00 2001 From: Austin Payne Date: Tue, 30 Apr 2024 23:26:07 -0600 Subject: [PATCH] improvement: pass down file/line via makeFutureWithResultOfTask In some circumstances it can be difficult to know which specific call to makeFutureWithTask leaked a promise. Adds a new function that passes down file/line to help aid debugging such situations. --- Sources/NIOCore/AsyncAwaitSupport.swift | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Sources/NIOCore/AsyncAwaitSupport.swift b/Sources/NIOCore/AsyncAwaitSupport.swift index 659df1ad70..c3bc36faf2 100644 --- a/Sources/NIOCore/AsyncAwaitSupport.swift +++ b/Sources/NIOCore/AsyncAwaitSupport.swift @@ -338,6 +338,7 @@ struct AsyncSequenceFromIterator: AsyncSeq @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) extension EventLoop { + @available(*, deprecated, renamed: "makeFutureWithResultOfTask", message: "Prefer makeFutureWithResultOfTask as it will track the original creator of the promise.") @inlinable public func makeFutureWithTask(_ body: @Sendable @escaping () async throws -> Return) -> EventLoopFuture { let promise = self.makePromise(of: Return.self) @@ -345,3 +346,24 @@ extension EventLoop { return promise.futureResult } } + +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +extension EventLoop { + /// Make a future whose body runs in an `async` function `body`. + /// + /// This function can be used to bridge the `async` world into an `EventLoopFuture`. + /// + /// - parameters: + /// - body: The `async` function to run. + /// - returns: A `Future` which completes when `body` finishes running. + @inlinable + public func makeFutureWithResultOfTask( + file: StaticString = #fileID, + line: UInt = #line, + _ body: @Sendable @escaping () async throws -> Return + ) -> EventLoopFuture { + let promise = self.makePromise(of: Return.self, file: file, line: line) + promise.completeWithTask(body) + return promise.futureResult + } +}