sharedcomponent.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. // Package sharedcomponent exposes util functionality for receivers and exporters
  4. // that need to share state between different signal types instances such as net.Listener or os.File.
  5. package sharedcomponent // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent"
  6. import (
  7. "context"
  8. "sync"
  9. "go.opentelemetry.io/collector/component"
  10. )
  11. // SharedComponents a map that keeps reference of all created instances for a given configuration,
  12. // and ensures that the shared state is started and stopped only once.
  13. type SharedComponents struct {
  14. comps map[any]*SharedComponent
  15. }
  16. // NewSharedComponents returns a new empty SharedComponents.
  17. func NewSharedComponents() *SharedComponents {
  18. return &SharedComponents{
  19. comps: make(map[any]*SharedComponent),
  20. }
  21. }
  22. // GetOrAdd returns the already created instance if exists, otherwise creates a new instance
  23. // and adds it to the map of references.
  24. func (scs *SharedComponents) GetOrAdd(key any, create func() component.Component) *SharedComponent {
  25. if c, ok := scs.comps[key]; ok {
  26. return c
  27. }
  28. newComp := &SharedComponent{
  29. Component: create(),
  30. removeFunc: func() {
  31. delete(scs.comps, key)
  32. },
  33. }
  34. scs.comps[key] = newComp
  35. return newComp
  36. }
  37. // SharedComponent ensures that the wrapped component is started and stopped only once.
  38. // When stopped it is removed from the SharedComponents map.
  39. type SharedComponent struct {
  40. component.Component
  41. startOnce sync.Once
  42. stopOnce sync.Once
  43. removeFunc func()
  44. }
  45. // Unwrap returns the original component.
  46. func (r *SharedComponent) Unwrap() component.Component {
  47. return r.Component
  48. }
  49. // Start implements component.Component.
  50. func (r *SharedComponent) Start(ctx context.Context, host component.Host) error {
  51. var err error
  52. r.startOnce.Do(func() {
  53. err = r.Component.Start(ctx, host)
  54. })
  55. return err
  56. }
  57. // Shutdown implements component.Component.
  58. func (r *SharedComponent) Shutdown(ctx context.Context) error {
  59. var err error
  60. r.stopOnce.Do(func() {
  61. err = r.Component.Shutdown(ctx)
  62. r.removeFunc()
  63. })
  64. return err
  65. }