Skip to content

Instantly share code, notes, and snippets.

@radianttap
Created November 7, 2024 09:00
Show Gist options
  • Save radianttap/38b73d9a8d78ccb86ab0680cb28e4bef to your computer and use it in GitHub Desktop.
Save radianttap/38b73d9a8d78ccb86ab0680cb28e4bef to your computer and use it in GitHub Desktop.
TaskQueue
import Foundation
public actor TaskQueue {
private let maxConcurrentTasks: Int
private var runningTasks = 0
private var queue: [CheckedContinuation<Void, Never>] = []
public init(maxConcurrentTasks: Int) {
self.maxConcurrentTasks = maxConcurrentTasks
}
public func enqueue<T: Sendable, E: Error>(_ task: @escaping @Sendable () async throws(E) -> T) async throws(E) -> T {
if runningTasks >= maxConcurrentTasks {
await withCheckedContinuation { continuation in
queue.append(continuation)
}
}
runningTasks += 1
defer {
runningTasks -= 1
if runningTasks < maxConcurrentTasks && !queue.isEmpty {
queue.removeFirst().resume()
}
}
return try await task()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment