-
Notifications
You must be signed in to change notification settings - Fork 15
/
memory.go
105 lines (93 loc) · 3.29 KB
/
memory.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package repository
import (
"fmt"
"sync"
"github.com/periskop-dev/periskop/metrics"
)
func NewMemoryRepository() ErrorsRepository {
return &memoryRepository{
AggregatedError: sync.Map{},
ResolvedErrors: sync.Map{},
}
}
type memoryRepository struct {
// map service name -> list of errors
AggregatedError sync.Map
// map service name -> set of resolved errors
ResolvedErrors sync.Map
targetsRepository
}
// GetErrors fetches the last numberOfErrors of each aggregation of errors for the given service
func (r *memoryRepository) GetErrors(serviceName string, numberOfErrors int) ([]ErrorAggregate, error) {
if value, ok := r.AggregatedError.Load(serviceName); ok {
prevErrors, _ := value.([]ErrorAggregate)
errors := make([]ErrorAggregate, 0, len(prevErrors))
for _, errorAggregate := range prevErrors {
maxErrors := len(errorAggregate.LatestErrors)
if numberOfErrors < maxErrors {
maxErrors = numberOfErrors
}
errorAggregate.LatestErrors = errorAggregate.LatestErrors[0:maxErrors]
errors = append(errors, errorAggregate)
}
return errors, nil
}
metrics.ServiceErrors.WithLabelValues("service_not_found").Inc()
return nil, fmt.Errorf("service %s not found", serviceName)
}
// ReplaceErrors replaces a lists of aggregated errors for the given service
func (r *memoryRepository) ReplaceErrors(serviceName string, errors []ErrorAggregate) {
r.AggregatedError.Store(serviceName, errors)
}
// GetServices fetches the list of unique services
func (r *memoryRepository) GetServices() []string {
keys := make([]string, 0)
r.AggregatedError.Range(func(key, value interface{}) bool {
k, _ := key.(string)
keys = append(keys, k)
return true
})
return keys
}
// ResolveError removes the error from list of errors and adds to the set of resolved errors
func (r *memoryRepository) ResolveError(serviceName string, key string) error {
if value, ok := r.AggregatedError.Load(serviceName); ok {
prevErrors, _ := value.([]ErrorAggregate)
errors := []ErrorAggregate{}
for _, errorAggregate := range prevErrors {
if errorAggregate.AggregationKey != key {
errors = append(errors, errorAggregate)
}
}
r.ReplaceErrors(serviceName, errors)
r.addToResolved(serviceName, key)
return nil
}
return fmt.Errorf("service %s not found", serviceName)
}
// addToResolved saves the error to resolved error set
func (r *memoryRepository) addToResolved(serviceName string, key string) {
if resolvedSet, ok := r.ResolvedErrors.Load(serviceName); ok {
resolvedSet := resolvedSet.(map[string]bool)
resolvedSet[key] = true
r.ResolvedErrors.Store(serviceName, resolvedSet)
} else {
r.ResolvedErrors.Store(serviceName, map[string]bool{key: true})
}
}
// RemoveResolved removes a resolved error from resolved error set
func (r *memoryRepository) RemoveResolved(serviceName string, key string) {
if resolvedSet, ok := r.ResolvedErrors.Load(serviceName); ok {
resolvedSet := resolvedSet.(map[string]bool)
delete(resolvedSet, key)
r.ResolvedErrors.Store(serviceName, resolvedSet)
}
}
// SearchResolved searches if an error is inside the set of resolved errors
func (r *memoryRepository) SearchResolved(serviceName string, key string) bool {
if resolvedSet, ok := r.ResolvedErrors.Load(serviceName); ok {
resolvedSet := resolvedSet.(map[string]bool)
return resolvedSet[key]
}
return false
}