Skip to content

Instantly share code, notes, and snippets.

@grdsdev
Last active November 9, 2023 21:57
Show Gist options
  • Select an option

  • Save grdsdev/0045838631d287305394773c93eed0ea to your computer and use it in GitHub Desktop.

Select an option

Save grdsdev/0045838631d287305394773c93eed0ea to your computer and use it in GitHub Desktop.
Auto manage cancellation of in flight tasks.
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