Beyond the basics of structured concurrency

https://developer.apple.com/videos/play/wwdc2023/10170/

Task hierarchy

Concurrent execution is triggered when

// Structured concurrency
async let future = ...

taskGroup.addTask {
	...
}

// Unstructured concurrency
Task { ... }

Task.detached { ... }

Prefer structured task

Task cancellation

Structured task are cancelled implicitly when leaving scope

// Polling
Task.isCancelled 
try Task.checkCancellation()

// Event-Driven
withTaskCancellationHandler(operation:, onCancel:)
// Cancellation and AsyncSequences

private final class OrderState: Sendable {
	let protectedIsRunning = ManagedAtomic<Bool>(true)
	var isRunning: Bool {
		get { protectedIsRunning.load(ordering: .acquiring) }
		set { protectedIsRunning.store(newValue, ordering: .relaxed) }
	}

	func cancel() {
		isRunning = false
	}
}

Propagates through the task tree

Seamlessly integrates with throwing errors

Event-driven cancellation handlers or explicit polling

Task priority

By default child task inherit priority from parent

Structured priority escalation

  • Lower priority tasks escalate priority when awaited on by a higher priority task
  • Escalation propagates through the task tree
  • Priority remains escalated until the task completes

Task group patterns

DiscardingTaskGroup releases resources immediately on task completion

Use the completion of one task to signal the creation of the next in a TaskGroup

Task-local values

// Task-local values
// Associating values with task trees
actor Kitchen {
	@TaskLocal static var orderID: Int?
	@TaskLocal static var cook: String?
	
	func logStatus() {
		print("Current cook: \(kitchen.cook ?? "none")")
	}
}

let kitchen = Kitchen()
await kitchen.logStatus() // Current cook: none
await Kitchen.$cook.withValue("Sakura") {
	await kitchen.logStatus() // Current cook: Sakura
}
await kitchen.logStatus() // Current cook: none

Attach metadata to the current task

Inherited by child tasks as well as Task {}

Low-level building block for context propagation

Task traces

Local profiling with Instruments

Swift Distributed Tracing

  • Open source package for server ecosystem
  • Provides an extensible instrumentation API
  • Similar to Swift Log and Swift Metrics