You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 23, 2021. It is now read-only.
`BaggageContext` is a minimal (zero-dependency) "context" library meant to "carry" baggage (metadata) for cross-cutting tools such as tracers.
7
-
It is purposefully not tied to any specific use-case (in the spirit of the [Tracing Plane paper](https://cs.brown.edu/~jcmace/papers/mace18universal.pdf)'s BaggageContext), however it should enable a vast majority of use cases cross-cutting tools need to support. Unlike mentioned in the paper, our `BaggageContext` does not implement its own serialization scheme (today).
8
+
`BaggageContext` is a minimal (zero-dependency) "context" library meant to "carry" baggage (metadata) for cross-cutting
9
+
tools such as tracers. It is purposefully not tied to any specific use-case (in the spirit of the
10
+
[Tracing Plane paper](https://cs.brown.edu/~jcmace/papers/mace18universal.pdf)'s BaggageContext). However, it should
11
+
enable a vast majority of use cases cross-cutting tools need to support. Unlike mentioned in the paper, our
12
+
`BaggageContext` does not implement its own serialization scheme (today).
8
13
9
-
See https://github.com/slashmo/gsoc-swift-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).
14
+
See https://github.com/slashmo/gsoc-swift-tracing for actual instrument types and implementations which can be used to
15
+
deploy various cross-cutting instruments all reusing the same baggage type. More information can be found in the
You can install the `BaggageContext` library through the Swift Package Manager. The library itself is called `Baggage`, so that's what you'd import in your Swift files.
20
+
You can install the `BaggageContext` library through the Swift Package Manager. The library itself is called `Baggage`,
21
+
so that's what you'd import in your Swift files.
14
22
15
23
```swift
16
24
dependencies: [
@@ -22,14 +30,92 @@ dependencies: [
22
30
]
23
31
```
24
32
33
+
## Usage
34
+
35
+
`BaggageContext` is intended to be used in conjunction with the instrumentation of distributed systems. To make this
36
+
instrumentation work, all parties involved operate on the same `BaggageContext` type. These are the three common
37
+
parties, in no specific order, and guidance on how to use `BaggageContext`:
38
+
39
+
### End Users - explicit context passing
40
+
41
+
You'll likely interact with some API that takes a context. In most cases you already have a context at hand so you
42
+
should pass that along. If you're certain you don't have a context at hand, pass along an empty one after thinking about
43
+
why that's the case.
44
+
45
+
**TODO**: Document the reasoning behind `.background` & `.TODO` once merged ([#26](#26))
46
+
47
+
While this might seem like a burden to take on, this will allow you to immediately add instrumentation (e.g. tracing)
48
+
once your application grows. Let's say your profiling some troublesome performance regressions. You won't have the time
49
+
to go through the entire system to start passing contexts around.
50
+
51
+
> TL;DR: You should always pass around `BaggageContext`, so that you're ready for when you need it.
52
+
53
+
Once you are ready to instrument your application, you already have everything in place to get going. Instead of each
54
+
instrument operating on its own context type they'll be using the same `BaggageContext` that you're already passing
55
+
around to the various instrumentable libraries & frameworks you make use of, so you're free to mix & match any
56
+
compatible instrument(s) 🙌 Check out the [swift-tracing](https://github.com/slashmo/gsoc-swift-tracing) repository for
In order for context-passing to feel consistent and Swifty among all server-side (and not only) libraries and frameworks
28
-
aiming to adopt `BaggageContext` (or any of its uses, such as Distributed Tracing), we suggest the following set of guidelines:
111
+
For context-passing to feel consistent and Swifty among all server-side (and not only) libraries and frameworks
112
+
aiming to adopt `BaggageContext` (or any of its uses, such as Distributed Tracing), we suggest the following set of
113
+
guidelines:
29
114
30
115
### Argument naming/positioning
31
116
32
-
In order to propagate baggage through function calls (and asynchronous-boundaries it may often be necessary to pass it explicitly (unless wrapper APIs are provided which handle the propagation automatically).
117
+
Propagating baggage context through your system is to be done explicitly, meaning as a parameter in function calls,
118
+
following the "flow" of execution.
33
119
34
120
When passing baggage context explicitly we strongly suggest sticking to the following style guideline:
35
121
@@ -38,16 +124,20 @@ When passing baggage context explicitly we strongly suggest sticking to the foll
3. Required function parameters, including required trailing closures (e.g. `(onNext elementHandler: (Value) -> ())`),
40
126
4. Defaulted function parameters, including optional trailing closures (e.g. `(onComplete completionHandler: (Reason) -> ()) = { _ in }`).
41
-
- Baggage Context should be passed as:**the last parameter in the required non-function parameters group in a function declaration**.
127
+
- Baggage Context should be passed as **the last parameter in the required non-function parameters group in a function declaration**.
42
128
43
-
This way when reading the call side, users of these APIs can learn to "ignore" or "skim over" the context parameter and the method signature remains human-readable and “Swifty”.
129
+
This way when reading the call side, users of these APIs can learn to "ignore" or "skim over" the context parameter and
130
+
the method signature remains human-readable and “Swifty”.
44
131
45
132
Examples:
46
133
47
134
-`func request(_ url: URL,`**`context: BaggageContext`**`)`, which may be called as `httpClient.request(url, context: context)`
- if a "framework context" exists and _carries_ the baggage context already, it is permitted to pass that context together with the baggage;
50
-
- it is _strongly recommended_ to store the baggage context as `baggage` property of `FrameworkContext` in such cases, in order to avoid the confusing spelling of `context.context`, and favoring the self-explanatory `context.baggage` spelling when the baggage is contained in a framework context object.
136
+
- if a "framework context" exists and _carries_ the baggage context already, it is permitted to pass that context
137
+
together with the baggage;
138
+
- it is _strongly recommended_ to store the baggage context as `baggage` property of `FrameworkContext` in such cases,
139
+
in order to avoid the confusing spelling of `context.context`, and favoring the self-explanatory `context.baggage`
140
+
spelling when the baggage is contained in a framework context object.
- pass the baggage as **last** of such non-domain specific parameters as it will be _by far more_ omnipresent than any specific framework parameter - as it is expected that any framework should be accepting a context if it is able to do so. While not all libraries are necessarily going to be implemented using the same frameworks.
151
+
- pass the baggage as **last** of such non-domain specific parameters as it will be _by far more_ omnipresent than any
152
+
specific framework parameter - as it is expected that any framework should be accepting a context if it can do so.
153
+
While not all libraries are necessarily going to be implemented using the same frameworks.
62
154
63
-
We feel it is important to preserve Swift's human-readable nature of function definitions. In other words, we intend to keep the read-out-loud phrasing of methods to remain _"request that url (ignore reading out loud the context parameter)"_ rather than _"request (ignore this context parameter when reading) that url"_.
155
+
We feel it is important to preserve Swift's human-readable nature of function definitions. In other words, we intend to
156
+
keep the read-out-loud phrasing of methods to remain _"request that URL (ignore reading out loud the context parameter)"_
157
+
rather than _"request (ignore this context parameter when reading) that URL"_.
64
158
65
159
#### When to use what context type?
66
160
67
161
This library defines the following context (carrier) types:
68
162
69
163
-`struct BaggageContext` - which is the actual context object,
70
-
-`protocol BaggageContextCarrier` - which should be used whenever a library implements an API and does not necessarily care where it gets a `context` value from
71
-
- this pattern enables other frameworks to pass their `FrameworkContext`, like so: `get(context: MyFrameworkContext())` if they already have such context in scope (e.g. Vapor's `Request` object is a good example, or Lambda Runtime's `Lambda.Context`
164
+
-`protocol BaggageContextCarrier` - which should be used whenever a library implements an API and does not necessarily
165
+
care where it gets a `context` value from
166
+
- this pattern enables other frameworks to pass their `FrameworkContext`, like so:
167
+
`get(context: MyFrameworkContext())` if they already have such context in scope (e.g. Vapor's `Request` object is a
168
+
good example, or Lambda Runtime's `Lambda.Context`
72
169
-`protocol LoggingBaggageContextCarrier` - which in addition exposes a logger bound to the passed context
73
170
74
-
Finally, some frameworks will have APIs which accept the specific `MyFrameworkContext`, withing frameworks specifically a lot more frequently than libraries one would hope. It is important when designing APIs to keep in mind -- can this API work with any context, or is it always going to require _my framework context_, and erring on accepting the most general type possible.
171
+
Finally, some frameworks will have APIs which accept the specific `MyFrameworkContext`, withing frameworks specifically
172
+
a lot more frequently than libraries one would hope. It is important when designing APIs to keep in mind -- can this API
173
+
work with any context, or is it always going to require _my framework context_, and erring on accepting the most
174
+
general type possible.
75
175
76
176
#### Existing context argument
77
177
78
-
When adapting an existing library/framework to support `BaggageContext` and it already has a "framework context" which is expected to be passed through "everywhere", we suggest to follow these guidelines to adopting BaggageContext:
79
-
80
-
1. Add a `BaggageContext` as a property called `baggage` to your own `context` type, so that the call side for your users becomes `context.baggage` (rather than the confusing `context.context`)
81
-
2. If you cannot or it would not make sense to carry baggage inside your framework's context object, pass (and accept (!)) the `BaggageContext` in your framework functions like follows:
82
-
- if they take no framework context, accept a `context: BaggageContext` which is the same guideline as for all other cases
83
-
- if they already _must_ take a context object and you are out of words (or your API already accepts your framework context as "context"), pass the baggage as **last** parameter (see above) yet call the parameter `baggage` to disambiguate your `context` object from the `baggage` context object.
178
+
When adapting an existing library/framework to support `BaggageContext` and it already has a "framework context" which
179
+
is expected to be passed through "everywhere", we suggest to follow these guidelines for adopting BaggageContext:
180
+
181
+
1. Add a `BaggageContext` as a property called `baggage` to your own `context` type, so that the call side for your
182
+
users becomes `context.baggage` (rather than the confusing `context.context`)
183
+
2. If you cannot or it would not make sense to carry baggage inside your framework's context object,
184
+
pass (and accept (!)) the `BaggageContext` in your framework functions like follows:
185
+
- if they take no framework context, accept a `context: BaggageContext` which is the same guideline as for all other
186
+
cases
187
+
- if they already _must_ take a context object and you are out of words (or your API already accepts your framework
188
+
context as "context"), pass the baggage as **last** parameter (see above) yet call the parameter `baggage` to
189
+
disambiguate your `context` object from the `baggage` context object.
0 commit comments