forked from globalsign/mgo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchaos.go
68 lines (59 loc) · 1.4 KB
/
chaos.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
package txn
import (
mrand "math/rand"
"time"
)
var chaosEnabled = false
var chaosSetting Chaos
// Chaos holds parameters for the failure injection mechanism.
type Chaos struct {
// KillChance is the 0.0 to 1.0 chance that a given checkpoint
// within the algorithm will raise an interruption that will
// stop the procedure.
KillChance float64
// SlowdownChance is the 0.0 to 1.0 chance that a given checkpoint
// within the algorithm will be delayed by Slowdown before
// continuing.
SlowdownChance float64
Slowdown time.Duration
// If Breakpoint is set, the above settings will only affect the
// named breakpoint.
Breakpoint string
}
// SetChaos sets the failure injection parameters to c.
func SetChaos(c Chaos) {
chaosSetting = c
chaosEnabled = c.KillChance > 0 || c.SlowdownChance > 0
}
func chaos(bpname string) {
if !chaosEnabled {
return
}
switch chaosSetting.Breakpoint {
case "", bpname:
kc := chaosSetting.KillChance
if kc > 0 && mrand.Intn(1000) < int(kc*1000) {
panic(chaosError{})
}
if bpname == "insert" {
return
}
sc := chaosSetting.SlowdownChance
if sc > 0 && mrand.Intn(1000) < int(sc*1000) {
time.Sleep(chaosSetting.Slowdown)
}
}
}
type chaosError struct{}
func (f *flusher) handleChaos(err *error) {
v := recover()
if v == nil {
return
}
if _, ok := v.(chaosError); ok {
f.debugf("Killed by chaos!")
*err = ErrChaos
return
}
panic(v)
}