context.go (2686B)
1 // Copyright The OpenTelemetry Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package baggage // import "go.opentelemetry.io/otel/internal/baggage" 16 17 import "context" 18 19 type baggageContextKeyType int 20 21 const baggageKey baggageContextKeyType = iota 22 23 // SetHookFunc is a callback called when storing baggage in the context. 24 type SetHookFunc func(context.Context, List) context.Context 25 26 // GetHookFunc is a callback called when getting baggage from the context. 27 type GetHookFunc func(context.Context, List) List 28 29 type baggageState struct { 30 list List 31 32 setHook SetHookFunc 33 getHook GetHookFunc 34 } 35 36 // ContextWithSetHook returns a copy of parent with hook configured to be 37 // invoked every time ContextWithBaggage is called. 38 // 39 // Passing nil SetHookFunc creates a context with no set hook to call. 40 func ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context { 41 var s baggageState 42 if v, ok := parent.Value(baggageKey).(baggageState); ok { 43 s = v 44 } 45 46 s.setHook = hook 47 return context.WithValue(parent, baggageKey, s) 48 } 49 50 // ContextWithGetHook returns a copy of parent with hook configured to be 51 // invoked every time FromContext is called. 52 // 53 // Passing nil GetHookFunc creates a context with no get hook to call. 54 func ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context { 55 var s baggageState 56 if v, ok := parent.Value(baggageKey).(baggageState); ok { 57 s = v 58 } 59 60 s.getHook = hook 61 return context.WithValue(parent, baggageKey, s) 62 } 63 64 // ContextWithList returns a copy of parent with baggage. Passing nil list 65 // returns a context without any baggage. 66 func ContextWithList(parent context.Context, list List) context.Context { 67 var s baggageState 68 if v, ok := parent.Value(baggageKey).(baggageState); ok { 69 s = v 70 } 71 72 s.list = list 73 ctx := context.WithValue(parent, baggageKey, s) 74 if s.setHook != nil { 75 ctx = s.setHook(ctx, list) 76 } 77 78 return ctx 79 } 80 81 // ListFromContext returns the baggage contained in ctx. 82 func ListFromContext(ctx context.Context) List { 83 switch v := ctx.Value(baggageKey).(type) { 84 case baggageState: 85 if v.getHook != nil { 86 return v.getHook(ctx, v.list) 87 } 88 return v.list 89 default: 90 return nil 91 } 92 }