1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-03-11 14:49:19 +02:00

use a sync.Map

This commit is contained in:
Joshua MacDonald 2021-09-21 12:37:53 -07:00
parent 989066bf0f
commit ea7bc599bd

View File

@ -57,7 +57,7 @@ var ErrControllerStarted = fmt.Errorf("controller already started")
// be blocked by a pull request in the basic controller. // be blocked by a pull request in the basic controller.
type Controller struct { type Controller struct {
lock sync.Mutex lock sync.Mutex
libraries map[instrumentation.Library]*registry.UniqueInstrumentMeterImpl libraries sync.Map // a map[instrumentation.Library]*initMeterOnce
checkpointerFactory export.CheckpointerFactory checkpointerFactory export.CheckpointerFactory
resource *resource.Resource resource *resource.Resource
@ -76,6 +76,11 @@ type Controller struct {
collectedTime time.Time collectedTime time.Time
} }
type initMeterOnce struct {
unique *registry.UniqueInstrumentMeterImpl
initOnce sync.Once
}
var _ export.InstrumentationLibraryReader = &Controller{} var _ export.InstrumentationLibraryReader = &Controller{}
var _ metric.MeterProvider = &Controller{} var _ metric.MeterProvider = &Controller{}
@ -87,21 +92,20 @@ func (c *Controller) Meter(instrumentationName string, opts ...metric.MeterOptio
SchemaURL: cfg.SchemaURL(), SchemaURL: cfg.SchemaURL(),
} }
c.lock.Lock() newTmp := &initMeterOnce{}
defer c.lock.Unlock() m, _ := c.libraries.LoadOrStore(library, newTmp)
m, ok := c.libraries[library] mo := m.(*initMeterOnce)
if !ok { mo.initOnce.Do(func() {
checkpointer := c.checkpointerFactory.NewCheckpointer() checkpointer := c.checkpointerFactory.NewCheckpointer()
accumulator := sdk.NewAccumulator(checkpointer) accumulator := sdk.NewAccumulator(checkpointer)
m = registry.NewUniqueInstrumentMeterImpl(&accumulatorCheckpointer{ mo.unique = registry.NewUniqueInstrumentMeterImpl(&accumulatorCheckpointer{
Accumulator: accumulator, Accumulator: accumulator,
checkpointer: checkpointer, checkpointer: checkpointer,
library: library, library: library,
}) })
})
c.libraries[library] = m return metric.WrapMeterImpl(mo.unique)
}
return metric.WrapMeterImpl(m)
} }
type accumulatorCheckpointer struct { type accumulatorCheckpointer struct {
@ -132,7 +136,6 @@ func New(checkpointerFactory export.CheckpointerFactory, opts ...Option) *Contro
} }
} }
return &Controller{ return &Controller{
libraries: map[instrumentation.Library]*registry.UniqueInstrumentMeterImpl{},
checkpointerFactory: checkpointerFactory, checkpointerFactory: checkpointerFactory,
exporter: c.Exporter, exporter: c.Exporter,
resource: c.Resource, resource: c.Resource,
@ -249,12 +252,14 @@ func (c *Controller) accumulatorList() []*accumulatorCheckpointer {
defer c.lock.Unlock() defer c.lock.Unlock()
var r []*accumulatorCheckpointer var r []*accumulatorCheckpointer
for _, entry := range c.libraries { c.libraries.Range(func(_, value interface{}) bool {
acc, ok := entry.MeterImpl().(*accumulatorCheckpointer) mo := value.(*initMeterOnce)
acc, ok := mo.unique.MeterImpl().(*accumulatorCheckpointer)
if ok { if ok {
r = append(r, acc) r = append(r, acc)
} }
} return true
})
return r return r
} }