Skip to content

Commit

Permalink
Make Add, Delete, GetAll associated with producer.Manager (census-ins…
Browse files Browse the repository at this point in the history
  • Loading branch information
rghetia authored Mar 4, 2019
1 parent f305e5c commit 8734d3b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 63 deletions.
55 changes: 22 additions & 33 deletions metric/producer/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,53 +18,54 @@ import (
"sync"
)

type manager struct {
// Manager maintains a list of active producers. Producers can register
// with the manager to allow readers to read all metrics provided by them.
// Readers can retrieve all producers registered with the manager,
// read metrics from the producers and export them.
type Manager struct {
mu sync.RWMutex
producers map[Producer]struct{}
}

var prodMgr *manager
var prodMgr *Manager
var once sync.Once

func getManager() *manager {
// GlobalManager is a single instance of producer manager
// that is used by all producers and all readers.
func GlobalManager() *Manager {
once.Do(func() {
prodMgr = &manager{}
prodMgr = &Manager{}
prodMgr.producers = make(map[Producer]struct{})
})
return prodMgr
}

// Add adds the producer to the manager if it is not already present.
// The manager maintains the list of active producers. It provides
// this list to a reader to read metrics from each producer and then export.
func Add(producer Producer) {
// AddProducer adds the producer to the Manager if it is not already present.
func (pm *Manager) AddProducer(producer Producer) {
if producer == nil {
return
}
pm := getManager()
pm.add(producer)
pm.mu.Lock()
defer pm.mu.Unlock()
pm.producers[producer] = struct{}{}
}

// Delete deletes the producer from the manager if it is present.
func Delete(producer Producer) {
// DeleteProducer deletes the producer from the Manager if it is present.
func (pm *Manager) DeleteProducer(producer Producer) {
if producer == nil {
return
}
pm := getManager()
pm.delete(producer)
pm.mu.Lock()
defer pm.mu.Unlock()
delete(pm.producers, producer)
}

// GetAll returns a slice of all producer currently registered with
// the manager. For each call it generates a new slice. The slice
// the Manager. For each call it generates a new slice. The slice
// should not be cached as registration may change at any time. It is
// typically called periodically by exporter to read metrics from
// the producers.
func GetAll() []Producer {
pm := getManager()
return pm.getAll()
}

func (pm *manager) getAll() []Producer {
func (pm *Manager) GetAll() []Producer {
pm.mu.Lock()
defer pm.mu.Unlock()
producers := make([]Producer, len(pm.producers))
Expand All @@ -75,15 +76,3 @@ func (pm *manager) getAll() []Producer {
}
return producers
}

func (pm *manager) add(producer Producer) {
pm.mu.Lock()
defer pm.mu.Unlock()
pm.producers[producer] = struct{}{}
}

func (pm *manager) delete(producer Producer) {
pm.mu.Lock()
defer pm.mu.Unlock()
delete(pm.producers, producer)
}
61 changes: 31 additions & 30 deletions metric/producer/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
myProd1 = newTestProducer("foo")
myProd2 = newTestProducer("bar")
myProd3 = newTestProducer("foobar")
pm = GlobalManager()
)

func newTestProducer(name string) *testProducer {
Expand All @@ -39,83 +40,83 @@ func (mp *testProducer) Read() []*metricdata.Metric {
}

func TestAdd(t *testing.T) {
Add(myProd1)
Add(myProd2)
pm.AddProducer(myProd1)
pm.AddProducer(myProd2)

got := GetAll()
got := pm.GetAll()
want := []*testProducer{myProd1, myProd2}
checkSlice(got, want, t)
deleteAll()
}

func TestAddExisting(t *testing.T) {
Add(myProd1)
Add(myProd2)
Add(myProd1)
pm.AddProducer(myProd1)
pm.AddProducer(myProd2)
pm.AddProducer(myProd1)

got := GetAll()
got := pm.GetAll()
want := []*testProducer{myProd2, myProd1}
checkSlice(got, want, t)
deleteAll()
}

func TestAddNil(t *testing.T) {
Add(nil)
pm.AddProducer(nil)

got := GetAll()
got := pm.GetAll()
want := []*testProducer{}
checkSlice(got, want, t)
deleteAll()
}

func TestDelete(t *testing.T) {
Add(myProd1)
Add(myProd2)
Add(myProd3)
Delete(myProd2)
pm.AddProducer(myProd1)
pm.AddProducer(myProd2)
pm.AddProducer(myProd3)
pm.DeleteProducer(myProd2)

got := GetAll()
got := pm.GetAll()
want := []*testProducer{myProd1, myProd3}
checkSlice(got, want, t)
deleteAll()
}

func TestDeleteNonExisting(t *testing.T) {
Add(myProd1)
Add(myProd3)
Delete(myProd2)
pm.AddProducer(myProd1)
pm.AddProducer(myProd3)
pm.DeleteProducer(myProd2)

got := GetAll()
got := pm.GetAll()
want := []*testProducer{myProd1, myProd3}
checkSlice(got, want, t)
deleteAll()
}

func TestDeleteNil(t *testing.T) {
Add(myProd1)
Add(myProd3)
Delete(nil)
pm.AddProducer(myProd1)
pm.AddProducer(myProd3)
pm.DeleteProducer(nil)

got := GetAll()
got := pm.GetAll()
want := []*testProducer{myProd1, myProd3}
checkSlice(got, want, t)
deleteAll()
}

func TestGetAllNil(t *testing.T) {
got := GetAll()
got := pm.GetAll()
want := []*testProducer{}
checkSlice(got, want, t)
deleteAll()
}

func TestImmutableProducerList(t *testing.T) {
Add(myProd1)
Add(myProd2)
pm.AddProducer(myProd1)
pm.AddProducer(myProd2)

producersToMutate := GetAll()
producersToMutate := pm.GetAll()
producersToMutate[0] = myProd3
got := GetAll()
got := pm.GetAll()
want := []*testProducer{myProd1, myProd2}
checkSlice(got, want, t)
deleteAll()
Expand All @@ -141,7 +142,7 @@ func checkSlice(got []Producer, want []*testProducer, t *testing.T) {
}

func deleteAll() {
Delete(myProd1)
Delete(myProd2)
Delete(myProd3)
pm.DeleteProducer(myProd1)
pm.DeleteProducer(myProd2)
pm.DeleteProducer(myProd3)
}

0 comments on commit 8734d3b

Please sign in to comment.