Skip to content

Commit 8bcd128

Browse files
docs: Adds documentation on manual propogation
**Motivation:** I work with a number of packages that are heavily NIO-based. I found it unclear how to create nested spans using this package in that environment where Task local variables were not preserved throughout EventLoopFuture chains. **Modifications:** This simply adds documentation for how to manually propogate spans by providing context arguments. It offers some examples that clarify that those contexts should come from started spans in order for trace IDs to be linked. **Result:** No functional changes, simply more thorough documentation.
1 parent bd2d421 commit 8bcd128

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

Sources/Tracing/Docs.docc/Guides/InstrumentYourLibrary.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,37 @@ actor MySampleServer {
207207

208208
While this code is very simple for illustration purposes, and it may seem surprising why there are two separate places where we need to call into user-code separately, in practice such situations can happen when using asynchronous network or database libraries which offer their API in terms of callbacks. Always consider if and when to restore context such that it makes sense for the end user.
209209

210+
#### Manual propogation
211+
212+
There are circumstances where `task-local` variables are interrupted during normal execution flow. One common instance is when using
213+
[`swift-nio`](https://github.com/apple/swift-nio)'s [`EventLoopFuture`](https://swiftpackageindex.com/apple/swift-nio/main/documentation/niocore/eventloopfuture) to chain asynchronous work. In these circumstances, the library can manually propogate the context metadata by taking the context of the parent span, and providing it into the `context` argument of the child span:
214+
215+
```swift
216+
// 1) start the parent span
217+
withSpan("parent") { span in
218+
let parentContext = span.context
219+
220+
// 2) start the child span, injecting the parent context
221+
withSpan("child", context: parentContext) { span in
222+
doSomething()
223+
}
224+
}
225+
```
226+
227+
Here's an example that uses Swift NIO's EventLoopFuture:
228+
229+
```swift
230+
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
231+
let parentSpan = startSpan("parent")
232+
group.any().makeSucceededVoidFuture().map { _ in
233+
withSpan("child", context: parentSpan.context) { span in
234+
doSomething()
235+
}
236+
}.always { _ in
237+
parentSpan.end()
238+
}
239+
```
240+
210241
### Starting Trace Spans in Your Library
211242

212243
The above steps are enough if you wanted to provide context propagation. It already enables techniques such as **correlation ids** which can be set once, in one system, and then carried through to any downstream services the code makes calls from while the context is set.

0 commit comments

Comments
 (0)