Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,19 @@ let package = Package(
]
),
],
dependencies: [
.package(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be changed before merging. And this defines the sequence of merges — SDT first, SSC follows.

url: "https://github.com/apple/swift-distributed-tracing.git",
from: "1.6.0"
)
],
targets: [
.target(name: "ServiceContextModule"),
.target(
name: "ServiceContextModule",
dependencies: [
.product(name: "Instrumentation", package: "swift-distributed-tracing")
]
),

// Deprecated/legacy module
.target(
Expand Down
81 changes: 34 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,73 +5,60 @@
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fapple%2Fswift-service-context%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/apple/swift-service-context)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fapple%2Fswift-service-context%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/apple/swift-service-context)

`ServiceContext` is a minimal (zero-dependency) context propagation container, intended to "carry" items for purposes of cross-cutting tools to be built on top of it.
> **This package is now a thin compatibility layer.** The implementation of `ServiceContext` moved into
> [swift-distributed-tracing](https://github.com/apple/swift-distributed-tracing), where the type is named
> `InstrumentationContext`. `import ServiceContextModule` keeps compiling and behaving exactly as it does
> today, with no code changes required.
>
> New projects, and existing ones that can freely update their code, should depend on
> swift-distributed-tracing directly and use `InstrumentationContext` (or `Tracing`, if they also need
> spans) instead of adding this package.

`ServiceContext` is a minimal context propagation container: a value type, propagated through task-local
storage, that carries arbitrary key-value pairs across concurrent Swift code.

It is modeled after the concepts explained in [W3C Baggage](https://w3c.github.io/baggage/) and
in the spirit of [Tracing Plane](https://cs.brown.edu/~jcmace/papers/mace18universal.pdf) 's "Baggage Context" type,
although by itself it does not define a specific serialization format.

See https://github.com/apple/swift-distributed-tracing for actual instrument types and implementations which can be used to
deploy various cross-cutting instruments all reusing the same baggage type. More information can be found in the
[SSWG meeting notes](https://gist.github.com/ktoso/4d160232407e4d5835b5ba700c73de37#swift-baggage-context--distributed-tracing).

## Overview

`ServiceContext` serves as currency type for carrying around additional contextual information between Swift tasks and functions.
## Dependency

One generally starts from a "top level" (empty) or the "current" (`ServiceContext.current`) context and then adds values to it.
If you already depend on this package, you do not need to change anything.
Comment thread
kukushechkin marked this conversation as resolved.

The context is a value type and is propagated using task-local values so it can be safely used from concurrent contexts like this:
For new code, depend on
[swift-distributed-tracing](https://github.com/apple/swift-distributed-tracing) directly instead:

```swift
var context = ServiceContext.topLevel
context[FirstTestKey.self] = 42

func exampleFunction() async -> Int {
guard let context = ServiceContext.current else {
return 0
}
guard let value = context[FirstTestKey.self] else {
return 0
}
print("test = \(value)") // test = 42
return value
}

let c = await ServiceContext.withValue(context) {
await exampleFunction()
}
assert(c == 42)
dependencies: [
.package(url: "https://github.com/apple/swift-distributed-tracing.git", from: "1.0.0")
]
```

`ServiceContext` is a fundamental building block for how distributed tracing propagates trace identifiers.
```swift
targets: [
.target(
name: "MyAwesomeApp",
dependencies: [
.product(name: "Tracing", package: "swift-distributed-tracing")
]
)
]
```

## Dependency
Depend on the `Instrumentation` product instead of `Tracing` if you only need context propagation, with no
tracing spans.

In order to depend on this library you can use the Swift Package Manager, and add the following dependency to your `Package.swift`:
### Existing dependents

```swift
dependencies: [
.package(
url: "https://github.com/apple/swift-service-context.git",
from: "1.0.0"
)
.package(url: "https://github.com/apple/swift-service-context.git", from: "1.0.0")
]
```

and depend on the module in your target:

```swift
targets: [
.target(
name: "MyAwesomeApp",
dependencies: [
.product(
name: "ServiceContextModule",
package: "swift-service-context"
),
.product(name: "ServiceContextModule", package: "swift-service-context")
]
),
// ...
)
]
```
26 changes: 26 additions & 0 deletions Sources/ServiceContextModule/CompatibilityShim.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Service Context open source project
//
// Copyright (c) 2020-2026 Apple Inc. and the Swift Service Context project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift Service Context project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// `ServiceContext`, `ServiceContextKey`, and `AnyServiceContextKey` now live in the
// `swift-distributed-tracing` package's `Instrumentation` module, renamed to `InstrumentationContext`,
// `InstrumentationContextKey`, and `AnyInstrumentationContextKey`. This module re-exports the module and
// declares its own, non-deprecated names so `import ServiceContextModule` keeps working unchanged, with no
// deprecation notice, for existing dependents of this package. `TODOLocation` kept its name, so this
// typealias just makes it reachable under this module too.
@_exported import Instrumentation

public typealias ServiceContext = Instrumentation.InstrumentationContext
public typealias ServiceContextKey = Instrumentation.InstrumentationContextKey
public typealias AnyServiceContextKey = Instrumentation.AnyInstrumentationContextKey
public typealias TODOLocation = Instrumentation.TODOLocation

This file was deleted.

28 changes: 0 additions & 28 deletions Sources/ServiceContextModule/Docs.docc/Reference/ServiceContext.md

This file was deleted.

This file was deleted.

15 changes: 12 additions & 3 deletions Sources/ServiceContextModule/Docs.docc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,18 @@ and implementations you can use to deploy various cross-cutting instruments that
More information can be found in the
[SSWG meeting notes](https://gist.github.com/ktoso/4d160232407e4d5835b5ba700c73de37#swift-baggage-context--distributed-tracing).

> Note: Automatic propagation through task-locals by using `ServiceContext.current` is supported in Swift version 5.5 or later.

## Getting started
Automatic propagation through task-locals by using `ServiceContext.current` is supported in Swift version 5.5 or later.

`ServiceContext`, `ServiceContextKey`, `AnyServiceContextKey`, and `TODOLocation` are
implemented in the `swift-distributed-tracing` package's `Instrumentation` module, where the first
three types are named `InstrumentationContext`, `InstrumentationContextKey`, and
`AnyInstrumentationContextKey`. `TODOLocation` keeps its name. This package declares its own,
non-deprecated names so existing dependents keep working unchanged, with no deprecation notice. New
code that also needs tracing spans should depend on `Tracing` directly, and new code with no existing
dependents to keep compatible should prefer `InstrumentationContext`, `InstrumentationContextKey`, and
`AnyInstrumentationContextKey`.

### Getting started

In order to depend on this library you can use the Swift Package Manager, and add the following dependency to your `Package.swift`:

Expand Down
Loading
Loading