Skip to content

Instantly share code, notes, and snippets.

@zmeyc
Created October 21, 2023 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zmeyc/8b12e0f63fc5a8872ad0541aee66b83e to your computer and use it in GitHub Desktop.
Save zmeyc/8b12e0f63fc5a8872ad0541aee66b83e to your computer and use it in GitHub Desktop.
Swift concurrency: multiple await for single result with loop
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