Created
October 21, 2023 19:24
-
-
Save zmeyc/8b12e0f63fc5a8872ad0541aee66b83e to your computer and use it in GitHub Desktop.
Swift concurrency: multiple await for single result with loop
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 | |
func generateSecureHash() async -> UUID { | |
print("Generating hash") | |
do { | |
try await Task.sleep(for: .seconds(100)) | |
} catch { | |
print("Sleep: \(error)") | |
} | |
print("Generating hash: done") | |
return UUID() | |
} | |
class SomeService { | |
private var hash: UUID? | |
private var isGeneratingHash = false | |
func doX() async { | |
let hash = await generateHash() | |
print("doX: \(hash)") | |
} | |
func doY() async { | |
let hash = await generateHash() | |
print("doY: \(hash)") | |
} | |
private func generateHash() async -> UUID { | |
while isGeneratingHash { | |
// await Task.yield() // high CPU usage | |
do { | |
// try await Task.sleep(for: .milliseconds(1)) // high CPU usage | |
try await Task.sleep(for: .milliseconds(100)) // low CPU usage, high latency | |
} catch { | |
print("Sleep: \(error)") | |
} | |
} | |
if let hash { return hash } | |
isGeneratingHash = true | |
defer { isGeneratingHash = false } | |
let hash = await generateSecureHash() | |
self.hash = hash | |
return hash | |
} | |
} | |
Task.detached { | |
let service = SomeService() | |
async let x: Void = service.doX() | |
async let y: Void = service.doY() | |
_ = await [x, y] | |
} | |
let sigintSrc = DispatchSource.makeSignalSource(signal: SIGINT, queue: .main) | |
sigintSrc.setEventHandler { | |
print("") | |
exit(0) | |
} | |
sigintSrc.resume() | |
RunLoop.current.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment