|
13 | 13 | # limitations under the License. |
14 | 14 |
|
15 | 15 | """ |
16 | | -This module implements experimental propagators to inject trace response context |
17 | | -into HTTP responses. This is useful for server side frameworks that start traces |
| 16 | +This module implements experimental propagators to inject trace context |
| 17 | +into response carriers. This is useful for server side frameworks that start traces |
18 | 18 | when server requests and want to share the trace context with the client so the |
19 | 19 | client can add it's spans to the same trace. |
20 | 20 |
|
@@ -44,25 +44,47 @@ def set_global_response_propagator(propagator): |
44 | 44 | _RESPONSE_PROPAGATOR = propagator |
45 | 45 |
|
46 | 46 |
|
47 | | -class DictHeaderSetter: |
| 47 | +class Setter(ABC): |
| 48 | + @abstractmethod |
| 49 | + def set(self, carrier, key, value): |
| 50 | + """Inject the provided key value pair in carrier.""" |
| 51 | + |
| 52 | + |
| 53 | +class DictHeaderSetter(Setter): |
48 | 54 | def set(self, carrier, key, value): # pylint: disable=no-self-use |
49 | 55 | old_value = carrier.get(key, "") |
50 | 56 | if old_value: |
51 | 57 | value = "{0}, {1}".format(old_value, value) |
52 | 58 | carrier[key] = value |
53 | 59 |
|
54 | 60 |
|
55 | | -default_setter = DictHeaderSetter() |
| 61 | +class FuncSetter(Setter): |
| 62 | + """FuncSetter coverts a function into a valid Setter. Any function that can |
| 63 | + set values in a carrier can be converted into a Setter by using FuncSetter. |
| 64 | + This is useful when injecting trace context into non-dict objects such |
| 65 | + HTTP Response objects for different framework. |
| 66 | +
|
| 67 | + For example, it can be used to create a setter for Falcon response object as: |
| 68 | +
|
| 69 | + setter = FuncSetter(falcon.api.Response.append_header) |
56 | 70 |
|
| 71 | + and then used with the propagator as: |
| 72 | +
|
| 73 | + propagator.inject(falcon_response, setter=setter) |
| 74 | +
|
| 75 | + This would essentially make the propagator call `falcon_response.append_header(key, value)` |
| 76 | + """ |
57 | 77 |
|
58 | | -class FuncSetter: |
59 | 78 | def __init__(self, func): |
60 | 79 | self._func = func |
61 | 80 |
|
62 | 81 | def set(self, carrier, key, value): |
63 | 82 | self._func(carrier, key, value) |
64 | 83 |
|
65 | 84 |
|
| 85 | +default_setter = DictHeaderSetter() |
| 86 | + |
| 87 | + |
66 | 88 | class ResponsePropagator(ABC): |
67 | 89 | @abstractmethod |
68 | 90 | def inject( |
@@ -100,5 +122,7 @@ def inject( |
100 | 122 | ), |
101 | 123 | ) |
102 | 124 | setter.set( |
103 | | - carrier, _HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, header_name, |
| 125 | + carrier, |
| 126 | + _HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, |
| 127 | + header_name, |
104 | 128 | ) |
0 commit comments