Gate

main

Swift Concurrency 'gate' type to control forward progress of async tasks.
wadetregaskis/Gate

Gate

GitHub code size in bytes GitHub build results

Swift Concurrency 'gate' type to control forward progress of async tasks.

A gate can be opened and closed, and while closed it cannot be entered. Async tasks can pass through the gate at appropriate point(s) in their execution (chosen by them, like checking for task cancellation). If the gate is closed at the time they try to enter it, they will pause and wait for it to open before proceeding.

The gate can be opened or closed from any code (not just async contexts).

An example use is in SwiftUI where you have background task(s) (e.g. from the task view modifier) that you want to pause & resume in response to state changes:

struct Example: View {
    let frames: NSImage

    @Binding var animate: Bool {
        didSet {
            guard animate != oldValue else { return }

            if animate {
                self.animationGate.open()
            } else {
                self.animationGate.close()
            }
        }
    }
    
    @State private var animationGate = Gate(initiallyOpen: true)

    @State var currentFrameIndex: Int = 0
    
    var body: some View {
        Image(nsImage: self.frames[self.currentFrameIndex])
            .task {
                while let _ = try? await self.animationGate.enter() {
                    self.currentFrameIndex = (self.currentFrameIndex + 1) % self.frames.count
                    try? await Task.sleep(for: .seconds(1) / 60)
                }
            }
    }
}

Note that enter will always throw if the task is cancelled, so you don't need to manually check for cancellation (e.g. Task.checkCancellation / Task.isCancelled) if you are using Gate entry like in the above example.

Thanks to…

This was inspired by (and based in part on) Gwendal Roué's Semaphore package.

Description

  • Swift Tools 5.5.0
View More Packages from this Author

Dependencies

  • None
Last updated: Thu Apr 18 2024 07:20:34 GMT-0900 (Hawaii-Aleutian Daylight Time)