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  }