1package txn 2 3import ( 4 mrand "math/rand" 5 "time" 6) 7 8var chaosEnabled = false 9var chaosSetting Chaos 10 11// Chaos holds parameters for the failure injection mechanism. 12type Chaos struct { 13 // KillChance is the 0.0 to 1.0 chance that a given checkpoint 14 // within the algorithm will raise an interruption that will 15 // stop the procedure. 16 KillChance float64 17 18 // SlowdownChance is the 0.0 to 1.0 chance that a given checkpoint 19 // within the algorithm will be delayed by Slowdown before 20 // continuing. 21 SlowdownChance float64 22 Slowdown time.Duration 23 24 // If Breakpoint is set, the above settings will only affect the 25 // named breakpoint. 26 Breakpoint string 27} 28 29// SetChaos sets the failure injection parameters to c. 30func SetChaos(c Chaos) { 31 chaosSetting = c 32 chaosEnabled = c.KillChance > 0 || c.SlowdownChance > 0 33} 34 35func chaos(bpname string) { 36 if !chaosEnabled { 37 return 38 } 39 switch chaosSetting.Breakpoint { 40 case "", bpname: 41 kc := chaosSetting.KillChance 42 if kc > 0 && mrand.Intn(1000) < int(kc*1000) { 43 panic(chaosError{}) 44 } 45 if bpname == "insert" { 46 return 47 } 48 sc := chaosSetting.SlowdownChance 49 if sc > 0 && mrand.Intn(1000) < int(sc*1000) { 50 time.Sleep(chaosSetting.Slowdown) 51 } 52 } 53} 54 55type chaosError struct{} 56 57func (f *flusher) handleChaos(err *error) { 58 v := recover() 59 if v == nil { 60 return 61 } 62 if _, ok := v.(chaosError); ok { 63 f.debugf("Killed by chaos!") 64 *err = ErrChaos 65 return 66 } 67 panic(v) 68} 69