Skip to content

Instantly share code, notes, and snippets.

@thomsmed
Created August 20, 2024 17:13
Show Gist options
  • Save thomsmed/90b535275f0fe4380cc84f0de71456a3 to your computer and use it in GitHub Desktop.
Save thomsmed/90b535275f0fe4380cc84f0de71456a3 to your computer and use it in GitHub Desktop.
Simple example on how to restrict access to one or more "resources" (local storage, remote endpoint, etc). Very similar to how one would use a semaphore for protected access.
//
// RestrictiveResourceLoader.swift
//
import Foundation
/// Simple example on how to restrict access to one or more "resources" (local storage, remote endpoint, etc).
/// Very similar to how one would use a semaphore for protected access.
final actor RestrictiveResourceLoader {
private var isFetchingResource: Bool = false
private var waitingContinuations: [CheckedContinuation<Void, Never>] = []
/// Wait for in line for the "resource(s)" to be available.
private func grab() async {
if isFetchingResource {
await withCheckedContinuation { continuation in
waitingContinuations.insert(continuation, at: 0)
}
}
isFetchingResource = true
}
/// Release the "resource(s)", making the "resource(s)" available for other callers.
private func release() {
// Make sure to either update `isFetchingResource` or resume next waiting continuation.
if let nextWaitingContinuation = waitingContinuations.popLast() {
nextWaitingContinuation.resume()
} else {
isFetchingResource = false
}
}
private func actuallyGrabResource() async throws -> String {
// Simulate some asynchronous work.
try await Task.sleep(for: .seconds(2))
return "Some text resource"
}
}
extension RestrictiveResourceLoader {
/// Restricting resource grabbing to only one task at the time.
///
/// Note: Cancelation could be handled better.
func grabResource() async throws -> String {
try Task.checkCancellation()
await grab()
defer { release() }
try Task.checkCancellation()
return try await actuallyGrabResource()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment