Skip to content

Commit bb90381

Browse files
Merge pull request #289 from newrelic/fix_race_condition_new_metric_set
Fix race condition when calling entityMetadata Key endpoint
2 parents 1f48f6c + 37a3d18 commit bb90381

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

integration/entity.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type EntityMetadata struct {
2929
Name string `json:"name"`
3030
Namespace string `json:"type"` // For compatibility reasons we keep the type.
3131
IDAttrs IDAttributes `json:"id_attributes"` // For entity Key uniqueness
32+
lock sync.Locker
3233
}
3334

3435
// EqualsTo returns true when both metadata are equal.
@@ -89,6 +90,7 @@ func newEntity(
8990
Name: name,
9091
Namespace: namespace,
9192
IDAttrs: idAttributes(idAttrs...),
93+
lock: &sync.Mutex{},
9294
},
9395
}
9496

@@ -105,7 +107,6 @@ func (e *Entity) SameAs(b *Entity) bool {
105107
if e.Metadata == nil || b.Metadata == nil {
106108
return false
107109
}
108-
109110
return e.Metadata.EqualsTo(b.Metadata)
110111
}
111112

integration/entity_id.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ func (k EntityKey) String() string {
3636

3737
// Key generates the entity key based on the entity metadata.
3838
func (m *EntityMetadata) Key() (EntityKey, error) {
39+
m.lock.Lock()
40+
defer m.lock.Unlock()
41+
3942
if len(m.Name) == 0 {
4043
return EmptyKey, nil // Empty value means this agent's default entity identifier
4144
}

integration/entity_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/newrelic/infra-integrations-sdk/data/attribute"
1212
"github.com/newrelic/infra-integrations-sdk/data/event"
13+
"github.com/newrelic/infra-integrations-sdk/data/metric"
1314
"github.com/newrelic/infra-integrations-sdk/persist"
1415
"github.com/stretchr/testify/assert"
1516
"github.com/stretchr/testify/require"
@@ -248,3 +249,29 @@ func TestEntity_SameAs(t *testing.T) {
248249
assert.True(t, e1.SameAs(e2))
249250
assert.False(t, e1.SameAs(e3))
250251
}
252+
253+
func TestEntity_NewMetricSet(t *testing.T) {
254+
i, err := New(integrationName, integrationVersion)
255+
256+
entity, err := i.Entity("a-name", "a-type")
257+
assert.NoError(t, err)
258+
259+
metricSetChan := make(chan *metric.Set)
260+
go func(e *Entity) {
261+
metricSetChan <- e.NewMetricSet("F5BigIpPoolMemberSample",
262+
attribute.Attribute{Key: "displayName", Value: "entityName"},
263+
attribute.Attribute{Key: "entityName", Value: "entityName"},
264+
attribute.Attribute{Key: "poolName", Value: "description"},
265+
attribute.Attribute{Key: "url", Value: "url"},
266+
)
267+
}(entity)
268+
269+
// We retrieve the entity at the same time to check for race conditions
270+
go func(i *Integration) {
271+
_, err := i.Entity("a-name", "a-type")
272+
assert.NoError(t, err)
273+
}(i)
274+
275+
metricSet := <-metricSetChan
276+
assert.NotEmpty(t, metricSet)
277+
}

0 commit comments

Comments
 (0)