Skip to content

Instantly share code, notes, and snippets.

@calebkleveter
Created January 24, 2020 15:23
Show Gist options
  • Save calebkleveter/277b6138a2e2d25dd71f62575dd79d0e to your computer and use it in GitHub Desktop.
Save calebkleveter/277b6138a2e2d25dd71f62575dd79d0e to your computer and use it in GitHub Desktop.
import NIO
public final class EventLoopFutureQueue {
public enum Continue {
case success
case failure
case complete
}
public enum ContinueError: Error {
case previousError(Error)
case previousSuccess
}
public let eventLoop: EventLoop
public var future: EventLoopFuture<Void> { self.current }
private var current: EventLoopFuture<Void>
public init(eventLoop: EventLoop) {
self.eventLoop = eventLoop
self.current = eventLoop.makeSucceededFuture(())
}
public func append<Value>(generator: @escaping () -> EventLoopFuture<Value>, runningOn next: Continue = .complete) -> EventLoopFuture<Value> {
let promise = self.eventLoop.makePromise(of: Void.self)
switch next {
case .success:
self.current.whenComplete { result in
switch result {
case .success: promise.succeed(())
case let .failure(error): promise.fail(ContinueError.previousError(error))
}
}
case .failure:
self.current.whenComplete { result in
switch result {
case .success: promise.fail(ContinueError.previousSuccess)
case .failure: promise.succeed(())
}
}
case .complete:
self.current.whenComplete { _ in promise.succeed(()) }
}
let next = promise.futureResult.flatMap { generator() }
self.current = next.map { _ in () }
return next
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment