Last active
July 26, 2019 15:56
-
-
Save zlangley/e6c7ea0b49f8a3cea0df35bd20c9c865 to your computer and use it in GitHub Desktop.
An operation queue for Promises.
This file contains 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
import Dispatch | |
import PromiseKit | |
/// A wrapper for a function that creates a Promise. | |
public class PromiseOperation<T> { | |
private let makePromise: () -> Promise<T> | |
public init(makePromise: @escaping () -> Promise<T>) { | |
self.makePromise = makePromise | |
} | |
/// Run the operation. | |
/// | |
/// - Returns: The `Promise` returned by the operation. | |
public func run() -> Promise<T> { | |
return makePromise() | |
} | |
/// Run the operation and block until it finishes. | |
/// | |
/// - Returns: The `Promise` returned by the operation. | |
public func runAndWait() -> Promise<T> { | |
let semaphore = DispatchSemaphore(value: 0) | |
let promise = makePromise().always(on: zalgo) { | |
semaphore.signal() | |
} | |
_ = semaphore.wait(timeout: DispatchTime.distantFuture) | |
return promise | |
} | |
} | |
/// An operation queue that may run `PromiseOperations` concurrently and supports | |
/// barrier operations. | |
public class PromiseQueue { | |
private let queue: DispatchQueue | |
internal init(queue: DispatchQueue) { | |
self.queue = queue | |
} | |
public init(name: String) { | |
self.init(queue: DispatchQueue(label: name, attributes: DispatchQueue.Attributes.concurrent)) | |
} | |
/// Submits an operation for asynchronous execution. | |
/// | |
/// - Parameter operation: The operation to run. | |
/// | |
/// - Returns: The `Promise` returned by running `operation`. | |
public func add<T>(_ operation: PromiseOperation<T>) -> Promise<T> { | |
return Promise(value: ()).then(on: queue) { Void -> Promise<T> in | |
return operation.runAndWait() | |
} | |
} | |
/// Submits a barrier operation for asynchronous execution. | |
/// | |
/// Submits an operation that will wait for all previously scheduled operations | |
/// in the queue to finish before starting, and prevents newer operations from | |
/// starting until the operation finishes. | |
/// | |
/// - Parameter operation: The operation to run as a barrier. | |
/// | |
/// - Returns: The `Promise` returned by running `operation`. | |
public func addBarrier<T>(_ operation: PromiseOperation<T>) -> Promise<T> { | |
return Promise(value: ()).then(on: .global()) { Void -> Promise<T> in | |
var promise: Promise<T>! | |
self.queue.sync(flags: .barrier, execute: { | |
promise = operation.runAndWait() | |
}) | |
return promise! | |
} | |
} | |
/// Submits a barrier block for asynchronous execution. | |
/// | |
/// Submits an operation that will wait for all previously scheduled operations | |
/// in the queue to finish before starting, and prevents newer operations from | |
/// starting until the `Promise` produced by `makePromise` resolves. | |
/// | |
/// - Parameter makePromise: The block to run as a barrier. | |
/// | |
/// - Returns: The `Promise` returned by running the block. | |
public func addBarrier<T>(_ makePromise: @escaping () -> Promise<T>) -> Promise<T> { | |
return addBarrier(PromiseOperation(makePromise: makePromise)) | |
} | |
} |
@TimurShafigullin IIRC, zalgo
was a special queue which would run the callback immediately. It might be long gone, I haven't worked with PromiseKit (or Swift for that matter) for a few years now.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is the property
zalgo
on line 24? @zlangley