Skip to content

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

License

Notifications You must be signed in to change notification settings

wadetregaskis/Gate

Repository files navigation

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.

About

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

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages