Created
January 28, 2023 12:25
-
-
Save finestructure/91f7d755c7d966751fd1a23e64b03013 to your computer and use it in GitHub Desktop.
ELF vs async/await behaviour test program
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
import Foundation | |
import NIO | |
extension Array where Element == EventLoopFuture<Void> { | |
/// Converts a collection of `EventLoopFuture<Void>`s to an `EventLoopFuture<Void>`. | |
/// | |
/// Acts as a helper for the `EventLoop.flatten(_:[EventLoopFuture<Value>])` method. | |
/// | |
/// let futures = [el.future(1), el.future(2), el.future(3), el.future(4)] | |
/// let flattened = futures.flatten(on: el) | |
/// // flattened: EventLoopFuture<Void> | |
/// | |
/// - parameter eventLoop: The event-loop to succeed the futures on. | |
/// - returns: The succeeded future. | |
public func flatten(on eventLoop: EventLoop) -> EventLoopFuture<Void> { | |
return .andAllSucceed(self, on: eventLoop) | |
} | |
} | |
struct Database { | |
var eventLoopGroup: EventLoopGroup | |
var eventLoop: EventLoop { | |
eventLoopGroup.next() | |
} | |
} | |
struct BuildTriggerInfo { | |
var packageId: Package.Id | |
var versionId: Int | |
var pairs = Array(0..<5) | |
} | |
func findMissingBuilds(_ database: Database, | |
packageId: Package.Id) -> EventLoopFuture<[BuildTriggerInfo]> { | |
database.eventLoop.makeSucceededFuture([ | |
BuildTriggerInfo(packageId: packageId, versionId: 0), | |
BuildTriggerInfo(packageId: packageId, versionId: 1), | |
]) | |
} | |
struct Response { | |
} | |
struct Build { | |
var id: UUID | |
static func trigger(database: Database) -> EventLoopFuture<Response> { | |
print("\(Date()): trigger") | |
sleep(1) | |
return database.eventLoop.makeSucceededFuture(.init()) | |
} | |
func create(on database: Database) -> EventLoopFuture<Void> { | |
database.eventLoop.makeSucceededVoidFuture() | |
} | |
} | |
func triggerBuildsUnchecked(on database: Database, | |
triggers: [BuildTriggerInfo]) -> EventLoopFuture<Void> { | |
print("triggerBuildsUnchecked: \(triggers.count) triggers") | |
return triggers.flatMap { trigger -> [EventLoopFuture<Void>] in | |
print("triggerBuildsUnchecked: \(trigger.pairs.count) triggers") | |
return trigger.pairs.map { pair in | |
return Build.trigger(database: database) | |
.flatMap { response in | |
Build(id: .init()).create(on: database) | |
} | |
} | |
} | |
.flatten(on: database.eventLoop) | |
} | |
struct Package { | |
typealias Id = Int | |
var id: Id | |
} | |
@main | |
public struct nio_test { | |
public static func main() async { | |
elf() | |
print("--------------------") | |
await asyncAwait() | |
} | |
static func elf() { | |
print("ELF") | |
let group = MultiThreadedEventLoopGroup(numberOfThreads: 8) | |
let database = Database(eventLoopGroup: group) | |
let packages = (0..<2) | |
let start = Date() | |
print("packages: 2") | |
try? packages.map { | |
findMissingBuilds(database, packageId: $0).flatMap { | |
triggerBuildsUnchecked(on: database, triggers: $0) } | |
} | |
.flatten(on: database.eventLoop) | |
.wait() | |
let elapsed = Date().timeIntervalSince(start) | |
print("elapsed: \(elapsed)") | |
} | |
static func asyncAwait() async { | |
print("asyncAwait") | |
let group = MultiThreadedEventLoopGroup(numberOfThreads: 8) | |
let database = Database(eventLoopGroup: group) | |
let packages = (0..<2) | |
let start = Date() | |
await withThrowingTaskGroup(of: Void.self) { group in | |
for package in packages { | |
group.addTask { | |
let triggerInfo = try await findMissingBuilds(database, packageId: package).get() | |
try await triggerBuildsUnchecked(on: database, triggers: triggerInfo).get() | |
} | |
} | |
} | |
let elapsed = Date().timeIntervalSince(start) | |
print("elapsed: \(elapsed)") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment