github.com/pingcap/chaos@v0.0.0-20190710112158-c86faf4b3719/pkg/core/nemesis.go (about) 1 package core 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 ) 8 9 // Nemesis injects failure and disturbs the database. 10 type Nemesis interface { 11 // // SetUp initializes the nemesis 12 // SetUp(ctx context.Context, node string) error 13 // // TearDown tears down the nemesis 14 // TearDown(ctx context.Context, node string) error 15 16 // Invoke executes the nemesis 17 Invoke(ctx context.Context, node string, args ...string) error 18 // Recover recovers the nemesis 19 Recover(ctx context.Context, node string, args ...string) error 20 // Name returns the unique name for the nemesis 21 Name() string 22 } 23 24 // NoopNemesis is a nemesis but does nothing 25 type NoopNemesis struct { 26 } 27 28 // // SetUp initializes the nemesis 29 // func (NoopNemesis) SetUp(ctx context.Context, node string) error { 30 // return nil 31 // } 32 33 // // TearDown tears down the nemesis 34 // func (NoopNemesis) TearDown(ctx context.Context, node string) error { 35 // return nil 36 // } 37 38 // Invoke executes the nemesis 39 func (NoopNemesis) Invoke(ctx context.Context, node string, args ...string) error { 40 return nil 41 } 42 43 // Recover recovers the nemesis 44 func (NoopNemesis) Recover(ctx context.Context, node string, args ...string) error { 45 return nil 46 } 47 48 // Name returns the unique name for the nemesis 49 func (NoopNemesis) Name() string { 50 return "noop" 51 } 52 53 var nemesises = map[string]Nemesis{} 54 55 // RegisterNemesis registers nemesis. Not thread-safe. 56 func RegisterNemesis(n Nemesis) { 57 name := n.Name() 58 _, ok := nemesises[name] 59 if ok { 60 panic(fmt.Sprintf("nemesis %s is already registered", name)) 61 } 62 63 nemesises[name] = n 64 } 65 66 // GetNemesis gets the registered nemesis. 67 func GetNemesis(name string) Nemesis { 68 return nemesises[name] 69 } 70 71 // NemesisOperation is nemesis operation used in control. 72 type NemesisOperation struct { 73 // Nemesis name 74 Name string 75 // Nemesis invoke args 76 InvokeArgs []string 77 // Nemesis recover args 78 RecoverArgs []string 79 // Nemesis execute time 80 RunTime time.Duration 81 } 82 83 // NemesisGenerator is used in control, it will generate a nemesis operation 84 // and then the control can use it to disturb the cluster. 85 type NemesisGenerator interface { 86 // Generate generates the nemesis operation for all nodes. 87 // Every node will be assigned a nemesis operation. 88 Generate(nodes []string) []*NemesisOperation 89 Name() string 90 } 91 92 // NoopNemesisGenerator generates 93 type NoopNemesisGenerator struct { 94 } 95 96 // Name returns the name 97 func (NoopNemesisGenerator) Name() string { 98 return "noop" 99 } 100 101 //Generate generates the nemesis operation for the nodes. 102 func (NoopNemesisGenerator) Generate(nodes []string) []*NemesisOperation { 103 ops := make([]*NemesisOperation, len(nodes)) 104 for i := 0; i < len(ops); i++ { 105 ops[i] = &NemesisOperation{ 106 Name: "noop", 107 InvokeArgs: nil, 108 RecoverArgs: nil, 109 RunTime: 0, 110 } 111 } 112 return ops 113 } 114 115 func init() { 116 RegisterNemesis(NoopNemesis{}) 117 }