Last active
June 5, 2024 15:44
-
-
Save robertmryan/bc5712e8c185848962eafe07d5137fa8 to your computer and use it in GitHub Desktop.
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
| actor Foo { | |
| private var firstTask: Task<Void, Error>? | |
| func performFirstTask() async throws { | |
| // create unstructured concurrency | |
| let task = Task { | |
| try await … // the work associated with first task | |
| } | |
| // save this task for future reference by other functions | |
| firstTask = task | |
| // because this is unstructured concurrency, we need to handle cancelation manually | |
| try await withTaskCancellationHandler { | |
| try await task.value | |
| } onCancel: { | |
| task.cancel() | |
| } | |
| } | |
| private func startOrAwaitFirstTask() async throws { | |
| if let firstTask { // see if first task has been started … | |
| try await firstTask.value // … if so, await it | |
| } else { | |
| try await performFirstTask() // … if not, start it | |
| } | |
| } | |
| func performSecondTask() async throws { | |
| try await startOrAwaitFirstTask() | |
| try await … // the work associated with second task | |
| } | |
| func performThirdTask() async throws { | |
| try await startOrAwaitFirstTask() | |
| try await … // the work associated with third task | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
By the way, note the use of
actorto avoid race onfirstTask. Alternatively, you could makefooaSendabletype, e.g., aclassisolated to some global actor. But you want to avoid races amongst these three tasks.