propagator.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package global // import "go.opentelemetry.io/otel/internal/global"
  4. import (
  5. "context"
  6. "sync"
  7. "go.opentelemetry.io/otel/propagation"
  8. )
  9. // textMapPropagator is a default TextMapPropagator that delegates calls to a
  10. // registered delegate if one is set, otherwise it defaults to delegating the
  11. // calls to a the default no-op propagation.TextMapPropagator.
  12. type textMapPropagator struct {
  13. mtx sync.Mutex
  14. once sync.Once
  15. delegate propagation.TextMapPropagator
  16. noop propagation.TextMapPropagator
  17. }
  18. // Compile-time guarantee that textMapPropagator implements the
  19. // propagation.TextMapPropagator interface.
  20. var _ propagation.TextMapPropagator = (*textMapPropagator)(nil)
  21. func newTextMapPropagator() *textMapPropagator {
  22. return &textMapPropagator{
  23. noop: propagation.NewCompositeTextMapPropagator(),
  24. }
  25. }
  26. // SetDelegate sets a delegate propagation.TextMapPropagator that all calls are
  27. // forwarded to. Delegation can only be performed once, all subsequent calls
  28. // perform no delegation.
  29. func (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {
  30. if delegate == nil {
  31. return
  32. }
  33. p.mtx.Lock()
  34. p.once.Do(func() { p.delegate = delegate })
  35. p.mtx.Unlock()
  36. }
  37. // effectiveDelegate returns the current delegate of p if one is set,
  38. // otherwise the default noop TextMapPropagator is returned. This method
  39. // can be called concurrently.
  40. func (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {
  41. p.mtx.Lock()
  42. defer p.mtx.Unlock()
  43. if p.delegate != nil {
  44. return p.delegate
  45. }
  46. return p.noop
  47. }
  48. // Inject set cross-cutting concerns from the Context into the carrier.
  49. func (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
  50. p.effectiveDelegate().Inject(ctx, carrier)
  51. }
  52. // Extract reads cross-cutting concerns from the carrier into a Context.
  53. func (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
  54. return p.effectiveDelegate().Extract(ctx, carrier)
  55. }
  56. // Fields returns the keys whose values are set with Inject.
  57. func (p *textMapPropagator) Fields() []string {
  58. return p.effectiveDelegate().Fields()
  59. }