Contents

swift-microservices/swift-operation-context

OperationContext is a lightweight, zero-dependency container for propagating typed values

Overview

Start with an empty OperationContext() for a new operation, or copy OperationContext.current to extend an existing one. Each key conforms to OperationContextKey and defines a Sendable value type. The context is a value type; changing a copy leaves the original container unchanged.

Bind a context with withContext(_:operation:) to make its values available throughout an operation and its structured child tasks:

import OperationContext

enum TenantIDKey: OperationContextKey {
    typealias Value = String
}

func readTenantID() async -> String? {
    OperationContext.current[TenantIDKey.self]
}

var context = OperationContext()
context[TenantIDKey.self] = "tenant-123"

let tenantID = await OperationContext.withContext(context) {
    async let inheritedTenantID = readTenantID()
    return await inheritedTenantID
}

assert(tenantID == "tenant-123")
assert(OperationContext.current[TenantIDKey.self] == nil)

current defaults to an empty context, and reading an unset key returns nil. Both synchronous and asynchronous withContext overloads restore the previous binding when the operation returns or throws. They bind the supplied context without merging it with the enclosing context.

Swift concurrency

Automatic propagation relies on Swift concurrency's task-local values. Use structured concurrency, including async let and task groups, to inherit the context while keeping child work within the operation's lifetime. The asynchronous withContext overload preserves caller actor isolation and runs in the existing task.

Unstructured Task { ... } also inherits the context, but can outlive the scope that created it. Task.detached { ... } does not inherit it. Detached work and framework callbacks need explicit capture and rebinding; network calls require explicit serialization. Synchronous code can also use the scoped API or pass a context directly.

Dependency

Requires Swift 6.3 or later. Supported platforms are Linux and macOS 15 or later.

Add the package to your Package.swift dependencies:

.package(url: "https://github.com/swift-microservices/swift-operation-context.git", from: "0.1.0")

Add the product to your target's dependencies:

.product(name: "OperationContext", package: "swift-operation-context")

Documentation

See the DocC documentation for key design, nested scopes, and propagation boundaries. Authentication, authorization, and database policy enforcement belong to consuming libraries; this package provides value propagation.

License

MIT. See LICENSE.

Package Metadata

Repository: swift-microservices/swift-operation-context

Default branch: main

README: README.md