Last active
November 9, 2023 21:57
-
-
Save grdsdev/0045838631d287305394773c93eed0ea to your computer and use it in GitHub Desktop.
Auto manage cancellation of in flight tasks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| protocol _CancellableTask { | |
| func cancel() | |
| } | |
| extension Task: _CancellableTask {} | |
| struct _TaskID: Hashable { | |
| let function: String | |
| let fileID: String | |
| let line: UInt | |
| } | |
| public actor TaskManager { | |
| private var tasks: [AnyHashable: _CancellableTask] = [:] | |
| public init() {} | |
| deinit { | |
| tasks.values.forEach { $0.cancel() } | |
| } | |
| @discardableResult | |
| public func add<Result>( | |
| id: AnyHashable? = nil, | |
| dismissInFlightTask: Bool = true, | |
| priority: TaskPriority? = nil, | |
| function: String = #function, | |
| line: UInt = #line, | |
| fileID: String = #fileID, | |
| _ block: @Sendable @escaping () async throws -> Result | |
| ) async throws -> Result { | |
| let id = id ?? _TaskID(function: function, fileID: fileID, line: line) as AnyHashable | |
| if dismissInFlightTask, let currentTask = tasks[id] { | |
| debugPrint("Cancelling in flight task: \(id)") | |
| currentTask.cancel() | |
| } | |
| let task = Task(priority: priority) { try await block() } | |
| tasks[id] = task | |
| return try await task.value | |
| } | |
| @discardableResult | |
| public func add<Result>( | |
| id: AnyHashable? = nil, | |
| dismissInFlightTask: Bool = true, | |
| priority: TaskPriority? = nil, | |
| function: String = #function, | |
| line: UInt = #line, | |
| fileID: String = #fileID, | |
| _ block: @escaping () async -> Result | |
| ) async -> Result { | |
| let id = id ?? _TaskID(function: function, fileID: fileID, line: line) as AnyHashable | |
| if dismissInFlightTask, let currentTask = tasks[id] { | |
| debugPrint("Cancelling in flight task: \(id)") | |
| currentTask.cancel() | |
| } | |
| let task = Task(priority: priority) { await block() } | |
| tasks[id] = task | |
| return await task.value | |
| } | |
| public func cancel(id: AnyHashable) { | |
| tasks[id]?.cancel() | |
| tasks[id] = nil | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment