Skip to content

Commit

Permalink
Fix duplicate TrackingIDs returned (#6960)
Browse files Browse the repository at this point in the history
There is a small chance the newTrackingID() function in tracking.go
will return the same id to multiple simultaneous callers.
The function must return the value returned by atomic.AddUint64()
to be safe.

(cherry picked from commit 9823952)
  • Loading branch information
asgaut authored and danielnelson committed Feb 4, 2020
1 parent 970fe90 commit c2e96e7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
3 changes: 1 addition & 2 deletions metric/tracking.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ var (
)

func newTrackingID() telegraf.TrackingID {
atomic.AddUint64(&lastID, 1)
return telegraf.TrackingID(lastID)
return telegraf.TrackingID(atomic.AddUint64(&lastID, 1))
}

func debugFinalizer(d *trackingData) {
Expand Down
38 changes: 38 additions & 0 deletions metric/tracking_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package metric

import (
"sync"
"testing"
"time"

Expand Down Expand Up @@ -30,6 +31,43 @@ func (d *deliveries) onDelivery(info telegraf.DeliveryInfo) {
d.Info[info.ID()] = info
}

func TestNewTrackingID(t *testing.T) {
var wg sync.WaitGroup
var a [100000]telegraf.TrackingID
var b [100000]telegraf.TrackingID

wg.Add(2)
go func() {
for i := 0; i < len(a); i++ {
a[i] = newTrackingID()
}
wg.Done()
}()
go func() {
for i := 0; i < len(b); i++ {
b[i] = newTrackingID()
}
wg.Done()
}()
wg.Wait()

// Find any duplicate TrackingIDs in arrays a and b. Arrays must be sorted in increasing order.
for i, j := 0, 0; i < len(a) && j < len(b); {
if a[i] == b[j] {
t.Errorf("Duplicate TrackingID: a[%d]==%d and b[%d]==%d.", i, a[i], j, b[j])
break
}
if a[i] > b[j] {
j++
continue
}
if a[i] < b[j] {
i++
continue
}
}
}

func TestTracking(t *testing.T) {
tests := []struct {
name string
Expand Down

0 comments on commit c2e96e7

Please sign in to comment.