/
wolf.go
51 lines (45 loc) · 983 Bytes
/
wolf.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
package missinggo
import (
"log"
"runtime"
"sync"
"sync/atomic"
)
const debug = false
// A Wolf represents some event that becomes less and less interesting as it
// occurs. Call CryHeard to see if we should pay attention this time.
type Wolf struct {
cries uint64
}
// Returns true less and less often. Convenient for exponentially decreasing
// the amount of noise due to errors.
func (me *Wolf) CryHeard() bool {
n := atomic.AddUint64(&me.cries, 1)
return n&(n-1) == 0
}
var (
mu sync.Mutex
wolves map[uintptr]*Wolf
)
// Calls CryHeard() on a Wolf that is unique to the callers program counter.
// i.e. every CryHeard() expression has its own Wolf.
func CryHeard() bool {
pc, file, line, ok := runtime.Caller(1)
if debug {
log.Println(pc, file, line, ok)
}
if !ok {
return true
}
mu.Lock()
if wolves == nil {
wolves = make(map[uintptr]*Wolf)
}
w, ok := wolves[pc]
if !ok {
w = new(Wolf)
wolves[pc] = w
}
mu.Unlock()
return w.CryHeard()
}