Skip to content

Commit bdf51ef

Browse files
committed
Return status of functions to add unit tests
1 parent ee19e2d commit bdf51ef

File tree

4 files changed

+62
-30
lines changed

4 files changed

+62
-30
lines changed

driver/sql/metrics.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ type (
44
// Metrics a structured metrics interface
55
Metrics interface {
66
ReceivedNotification(isNotification bool)
7-
QueueNotification(notification *ProjectionNotification)
8-
StartNotificationProcessing(notification *ProjectionNotification)
9-
FinishNotificationProcessing(notification *ProjectionNotification, success bool)
7+
QueueNotification(notification *ProjectionNotification) bool
8+
StartNotificationProcessing(notification *ProjectionNotification) bool
9+
FinishNotificationProcessing(notification *ProjectionNotification, success bool) bool
1010
}
1111
)

driver/sql/metrics_nop.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ var NopMetrics Metrics = &nopMetrics{}
55

66
type nopMetrics struct{}
77

8-
func (nm *nopMetrics) ReceivedNotification(isNotification bool) {}
9-
func (nm *nopMetrics) QueueNotification(notification *ProjectionNotification) {}
10-
func (nm *nopMetrics) StartNotificationProcessing(notification *ProjectionNotification) {}
11-
func (nm *nopMetrics) FinishNotificationProcessing(notification *ProjectionNotification, success bool) {
8+
func (nm *nopMetrics) ReceivedNotification(isNotification bool) {}
9+
func (nm *nopMetrics) QueueNotification(notification *ProjectionNotification) bool {
10+
return true
11+
}
12+
func (nm *nopMetrics) StartNotificationProcessing(notification *ProjectionNotification) bool {
13+
return true
14+
}
15+
func (nm *nopMetrics) FinishNotificationProcessing(notification *ProjectionNotification, success bool) bool {
16+
return true
1217
}

extension/prometheus/prometheus.go

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import (
1010
"github.com/prometheus/client_golang/prometheus"
1111
)
1212

13-
const namespace = "goengine"
13+
const (
14+
namespace = "goengine"
15+
notificationQueueKeyPrefix = "q"
16+
notificationProcessingKeyPrefix = "p"
17+
)
1418

1519
// Metrics is an object for exposing prometheus metrics
1620
type Metrics struct {
@@ -78,24 +82,38 @@ func (m *Metrics) ReceivedNotification(isNotification bool) {
7882
}
7983

8084
// QueueNotification returns http handler for prometheus
81-
func (m *Metrics) QueueNotification(notification *sql.ProjectionNotification) {
82-
key := "q" + fmt.Sprintf("%p", notification)
83-
m.notificationStartTimes.Store(key, time.Now())
85+
func (m *Metrics) QueueNotification(notification *sql.ProjectionNotification) bool {
86+
return m.storeStartTime(notificationQueueKeyPrefix, notification)
8487
}
8588

8689
// StartNotificationProcessing is used to record start time of notification processing
87-
func (m *Metrics) StartNotificationProcessing(notification *sql.ProjectionNotification) {
88-
key := "p" + fmt.Sprintf("%p", notification)
89-
m.notificationStartTimes.Store(key, time.Now())
90+
func (m *Metrics) StartNotificationProcessing(notification *sql.ProjectionNotification) bool {
91+
return m.storeStartTime(notificationProcessingKeyPrefix, notification)
9092
}
9193

9294
// FinishNotificationProcessing is used to observe end time of notification queue and processing time
93-
func (m *Metrics) FinishNotificationProcessing(notification *sql.ProjectionNotification, success bool) {
95+
func (m *Metrics) FinishNotificationProcessing(notification *sql.ProjectionNotification, success bool) bool {
9496
memAddress := fmt.Sprintf("%p", notification)
95-
queueStartTime, _ := m.notificationStartTimes.Load("q" + memAddress)
96-
processingStartTime, _ := m.notificationStartTimes.Load("p" + memAddress)
9797
labels := prometheus.Labels{"success": strconv.FormatBool(success)}
9898

99-
m.notificationQueueDuration.With(labels).Observe(time.Since(queueStartTime.(time.Time)).Seconds())
100-
m.notificationProcessingDuration.With(labels).Observe(time.Since(processingStartTime.(time.Time)).Seconds())
99+
queueStartTime, queueOk := m.notificationStartTimes.Load(notificationQueueKeyPrefix + memAddress)
100+
101+
processingStartTime, processingOk := m.notificationStartTimes.Load(notificationProcessingKeyPrefix + memAddress)
102+
103+
if processingOk && queueOk {
104+
m.notificationProcessingDuration.With(labels).Observe(time.Since(processingStartTime.(time.Time)).Seconds())
105+
m.notificationQueueDuration.With(labels).Observe(time.Since(queueStartTime.(time.Time)).Seconds())
106+
return true
107+
}
108+
109+
return false
110+
}
111+
112+
// storeStartTime stores the start time against each notification only if it's not already existent
113+
func (m *Metrics) storeStartTime(prefix string, notification *sql.ProjectionNotification) bool {
114+
key := prefix + fmt.Sprintf("%p", notification)
115+
116+
_, alreadyExists := m.notificationStartTimes.LoadOrStore(key, time.Now())
117+
118+
return !alreadyExists
101119
}
Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,43 @@
11
// +build unit
22

3-
package prometheus
3+
package prometheus_test
44

55
import (
6-
"fmt"
76
"testing"
8-
"time"
97

8+
"github.com/hellofresh/goengine/extension/prometheus"
109
"github.com/stretchr/testify/assert"
1110

1211
"github.com/hellofresh/goengine/driver/sql"
1312
)
1413

1514
func TestPrometheusMetrics(t *testing.T) {
16-
metrics := NewMetrics()
15+
metrics := prometheus.NewMetrics()
1716

1817
testSQLProjection := sql.ProjectionNotification{
1918
No: 1,
2019
AggregateID: "C56A4180-65AA-42EC-A945-5FD21DEC0538",
2120
}
2221

23-
metrics.QueueNotification(&testSQLProjection)
24-
metrics.StartNotificationProcessing(&testSQLProjection)
22+
ok := metrics.FinishNotificationProcessing(&testSQLProjection, true)
23+
assert.False(t, ok)
2524

26-
memAddress := fmt.Sprintf("%p", &testSQLProjection)
27-
queueStartTime, ok := metrics.notificationStartTimes.Load("q" + memAddress)
25+
ok = metrics.QueueNotification(&testSQLProjection)
2826
assert.True(t, ok)
29-
assert.IsType(t, time.Time{}, queueStartTime)
3027

31-
processingStartTime, _ := metrics.notificationStartTimes.Load("p" + memAddress)
28+
ok = metrics.QueueNotification(&testSQLProjection)
29+
assert.False(t, ok)
30+
31+
ok = metrics.FinishNotificationProcessing(&testSQLProjection, true)
32+
assert.False(t, ok)
33+
34+
ok = metrics.StartNotificationProcessing(&testSQLProjection)
35+
assert.True(t, ok)
36+
37+
ok = metrics.StartNotificationProcessing(&testSQLProjection)
38+
assert.False(t, ok)
39+
40+
ok = metrics.FinishNotificationProcessing(&testSQLProjection, true)
3241
assert.True(t, ok)
33-
assert.IsType(t, time.Time{}, processingStartTime)
42+
3443
}

0 commit comments

Comments
 (0)