forked from DataDog/datadog-agent
/
blocked_endpoints.go
68 lines (54 loc) · 1.41 KB
/
blocked_endpoints.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
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2018 Datadog, Inc.
package forwarder
import (
"sync"
"time"
)
const (
blockInterval time.Duration = 5 * time.Second
maxBlockInterval time.Duration = 30 * time.Second
)
type block struct {
nbError int
until time.Time
}
type blockedEndpoints struct {
errorPerEndpoint map[string]*block
m sync.RWMutex
}
func newBlockedEndpoints() *blockedEndpoints {
return &blockedEndpoints{errorPerEndpoint: make(map[string]*block)}
}
func (e *blockedEndpoints) block(endpointName string) {
e.m.Lock()
defer e.m.Unlock()
var b *block
if knownBlock, ok := e.errorPerEndpoint[endpointName]; ok {
b = knownBlock
} else {
b = &block{}
}
b.nbError++
newInterval := time.Duration(b.nbError) * blockInterval
if newInterval > maxRetryInterval {
newInterval = maxBlockInterval
}
b.until = time.Now().Add(newInterval)
e.errorPerEndpoint[endpointName] = b
}
func (e *blockedEndpoints) unblock(endpoint string) {
e.m.Lock()
defer e.m.Unlock()
delete(e.errorPerEndpoint, endpoint)
}
func (e *blockedEndpoints) isBlock(endpoint string) bool {
e.m.RLock()
defer e.m.RUnlock()
if b, ok := e.errorPerEndpoint[endpoint]; ok && time.Now().Before(b.until) {
return true
}
return false
}