github.com/matrixorigin/matrixone@v1.2.0/pkg/hakeeper/operator/controller.go (about)

     1  // Copyright 2020 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  // Portions of this file are additionally subject to the following
    15  // copyright.
    16  //
    17  // Copyright (C) 2021 Matrix Origin.
    18  //
    19  // Modified the behavior of the operator controller.
    20  
    21  package operator
    22  
    23  import (
    24  	"github.com/matrixorigin/matrixone/pkg/catalog"
    25  	pb "github.com/matrixorigin/matrixone/pkg/pb/logservice"
    26  )
    27  
    28  // Controller is used to manage operators.
    29  type Controller struct {
    30  	// operators is a map from shardID to its operators.
    31  	operators map[uint64][]*Operator
    32  }
    33  
    34  func NewController() *Controller {
    35  	return &Controller{
    36  		operators: make(map[uint64][]*Operator),
    37  	}
    38  }
    39  
    40  // RemoveOperator removes an operator from the operators.
    41  func (c *Controller) RemoveOperator(op *Operator) bool {
    42  	removed := c.removeOperator(op)
    43  	if removed {
    44  		_ = op.Cancel()
    45  	}
    46  	return removed
    47  }
    48  
    49  func (c *Controller) removeOperator(op *Operator) bool {
    50  	for i, curOp := range c.operators[op.shardID] {
    51  		if curOp == op {
    52  			c.operators[op.shardID] = append(c.operators[op.shardID][:i], c.operators[op.shardID][i+1:]...)
    53  			if len(c.operators[op.shardID]) == 0 {
    54  				delete(c.operators, op.shardID)
    55  			}
    56  			return true
    57  		}
    58  	}
    59  	return false
    60  }
    61  
    62  // GetOperators gets operators from the given shard.
    63  func (c *Controller) GetOperators(shardID uint64) []*Operator {
    64  	return c.operators[shardID]
    65  }
    66  
    67  type ExecutingReplicas struct {
    68  	Adding   map[uint64][]uint64
    69  	Removing map[uint64][]uint64
    70  	Starting map[uint64][]uint64
    71  }
    72  
    73  func (c *Controller) GetExecutingReplicas() ExecutingReplicas {
    74  	executing := ExecutingReplicas{
    75  		Adding:   make(map[uint64][]uint64),
    76  		Removing: make(map[uint64][]uint64),
    77  		Starting: make(map[uint64][]uint64),
    78  	}
    79  	for shardID, operators := range c.operators {
    80  		for _, op := range operators {
    81  			for _, step := range op.steps {
    82  				switch step := step.(type) {
    83  				case RemoveLogService:
    84  					executing.Removing[shardID] = append(executing.Removing[shardID], step.ReplicaID)
    85  				case AddLogService:
    86  					executing.Adding[shardID] = append(executing.Adding[shardID], step.ReplicaID)
    87  				case StartLogService:
    88  					executing.Starting[shardID] = append(executing.Starting[shardID], step.ReplicaID)
    89  				}
    90  			}
    91  		}
    92  	}
    93  	return executing
    94  }
    95  
    96  func (c *Controller) RemoveFinishedOperator(
    97  	logState pb.LogState, tnState pb.TNState, cnState pb.CNState, proxyState pb.ProxyState,
    98  ) {
    99  	for _, ops := range c.operators {
   100  		for _, op := range ops {
   101  			op.Check(logState, tnState, cnState, proxyState)
   102  			switch op.Status() {
   103  			case SUCCESS, EXPIRED:
   104  				c.RemoveOperator(op)
   105  			}
   106  		}
   107  	}
   108  }
   109  
   110  func (c *Controller) Dispatch(ops []*Operator, logState pb.LogState,
   111  	tnState pb.TNState, cnState pb.CNState, proxyState pb.ProxyState) (commands []pb.ScheduleCommand) {
   112  	for _, op := range ops {
   113  		c.operators[op.shardID] = append(c.operators[op.shardID], op)
   114  		if step := op.Check(logState, tnState, cnState, proxyState); step != nil {
   115  			commands = append(commands, generateScheduleCommand(step))
   116  		}
   117  	}
   118  	return
   119  }
   120  
   121  func generateScheduleCommand(step OpStep) pb.ScheduleCommand {
   122  	switch st := step.(type) {
   123  	case AddLogService:
   124  		return addLogService(st)
   125  	case RemoveLogService:
   126  		return removeLogService(st)
   127  	case StartLogService:
   128  		return startLogService(st)
   129  	case StopLogService:
   130  		return stopLogService(st)
   131  	case KillLogZombie:
   132  		return killLogZombie(st)
   133  	case AddTnReplica:
   134  		return addTnReplica(st)
   135  	case RemoveTnReplica:
   136  		return removeTnReplica(st)
   137  	case StopTnStore:
   138  		return stopTnStore(st)
   139  	case StopLogStore:
   140  		return stopLogStore(st)
   141  	case CreateTaskService:
   142  		return createTaskService(st)
   143  	case DeleteCNStore:
   144  		return deleteCNStore(st)
   145  	case JoinGossipCluster:
   146  		return joinGossipCluster(st)
   147  	case DeleteProxyStore:
   148  		return deleteProxyStore(st)
   149  	}
   150  	panic("invalid schedule command")
   151  }
   152  
   153  func addLogService(st AddLogService) pb.ScheduleCommand {
   154  	return pb.ScheduleCommand{
   155  		UUID: st.Target,
   156  		ConfigChange: &pb.ConfigChange{
   157  			Replica: pb.Replica{
   158  				UUID:      st.UUID,
   159  				ShardID:   st.ShardID,
   160  				ReplicaID: st.ReplicaID,
   161  				Epoch:     st.Epoch,
   162  			},
   163  			ChangeType: pb.AddReplica,
   164  		},
   165  		ServiceType: pb.LogService,
   166  	}
   167  }
   168  
   169  func removeLogService(st RemoveLogService) pb.ScheduleCommand {
   170  	return pb.ScheduleCommand{
   171  		UUID: st.Target,
   172  		ConfigChange: &pb.ConfigChange{
   173  			Replica: pb.Replica{
   174  				UUID:      st.UUID,
   175  				ShardID:   st.ShardID,
   176  				ReplicaID: st.ReplicaID,
   177  				Epoch:     st.Epoch,
   178  			},
   179  			ChangeType: pb.RemoveReplica,
   180  		},
   181  		ServiceType: pb.LogService,
   182  	}
   183  }
   184  
   185  func startLogService(st StartLogService) pb.ScheduleCommand {
   186  	return pb.ScheduleCommand{
   187  		UUID: st.UUID,
   188  		ConfigChange: &pb.ConfigChange{
   189  			Replica: pb.Replica{
   190  				UUID:      st.UUID,
   191  				ShardID:   st.ShardID,
   192  				ReplicaID: st.ReplicaID,
   193  			},
   194  			ChangeType: pb.StartReplica,
   195  		},
   196  		ServiceType: pb.LogService,
   197  	}
   198  }
   199  
   200  func stopLogService(st StopLogService) pb.ScheduleCommand {
   201  	return pb.ScheduleCommand{
   202  		UUID: st.UUID,
   203  		ConfigChange: &pb.ConfigChange{
   204  			Replica: pb.Replica{
   205  				UUID:    st.UUID,
   206  				ShardID: st.ShardID,
   207  				Epoch:   st.Epoch,
   208  			},
   209  			ChangeType: pb.RemoveReplica,
   210  		},
   211  		ServiceType: pb.LogService,
   212  	}
   213  }
   214  
   215  func killLogZombie(st KillLogZombie) pb.ScheduleCommand {
   216  	return pb.ScheduleCommand{
   217  		UUID:          st.UUID,
   218  		Bootstrapping: false,
   219  		ConfigChange: &pb.ConfigChange{
   220  			Replica: pb.Replica{
   221  				UUID:      st.UUID,
   222  				ShardID:   st.ShardID,
   223  				ReplicaID: st.ReplicaID,
   224  			},
   225  			ChangeType: pb.KillZombie,
   226  		},
   227  		ServiceType: pb.LogService,
   228  	}
   229  }
   230  
   231  func addTnReplica(st AddTnReplica) pb.ScheduleCommand {
   232  	return pb.ScheduleCommand{
   233  		UUID: st.StoreID,
   234  		ConfigChange: &pb.ConfigChange{
   235  			Replica: pb.Replica{
   236  				UUID:       st.StoreID,
   237  				ShardID:    st.ShardID,
   238  				ReplicaID:  st.ReplicaID,
   239  				LogShardID: st.LogShardID,
   240  			},
   241  			ChangeType: pb.StartReplica,
   242  		},
   243  		ServiceType: pb.TNService,
   244  	}
   245  }
   246  
   247  func removeTnReplica(st RemoveTnReplica) pb.ScheduleCommand {
   248  	return pb.ScheduleCommand{
   249  		UUID: st.StoreID,
   250  		ConfigChange: &pb.ConfigChange{
   251  			Replica: pb.Replica{
   252  				UUID:       st.StoreID,
   253  				ShardID:    st.ShardID,
   254  				ReplicaID:  st.ReplicaID,
   255  				LogShardID: st.LogShardID,
   256  			},
   257  			ChangeType: pb.StopReplica,
   258  		},
   259  		ServiceType: pb.TNService,
   260  	}
   261  }
   262  
   263  func stopTnStore(st StopTnStore) pb.ScheduleCommand {
   264  	return pb.ScheduleCommand{
   265  		UUID: st.StoreID,
   266  		ShutdownStore: &pb.ShutdownStore{
   267  			StoreID: st.StoreID,
   268  		},
   269  		ServiceType: pb.TNService,
   270  	}
   271  }
   272  
   273  func stopLogStore(st StopLogStore) pb.ScheduleCommand {
   274  	return pb.ScheduleCommand{
   275  		UUID: st.StoreID,
   276  		ShutdownStore: &pb.ShutdownStore{
   277  			StoreID: st.StoreID,
   278  		},
   279  		ServiceType: pb.LogService,
   280  	}
   281  }
   282  
   283  func createTaskService(st CreateTaskService) pb.ScheduleCommand {
   284  	return pb.ScheduleCommand{
   285  		UUID:        st.StoreID,
   286  		ServiceType: st.StoreType,
   287  		CreateTaskService: &pb.CreateTaskService{
   288  			User:         st.TaskUser,
   289  			TaskDatabase: catalog.MOTaskDB,
   290  		},
   291  	}
   292  }
   293  
   294  func deleteCNStore(st DeleteCNStore) pb.ScheduleCommand {
   295  	return pb.ScheduleCommand{
   296  		UUID:        st.StoreID,
   297  		ServiceType: pb.CNService,
   298  		DeleteCNStore: &pb.DeleteCNStore{
   299  			StoreID: st.StoreID,
   300  		},
   301  	}
   302  }
   303  
   304  func joinGossipCluster(st JoinGossipCluster) pb.ScheduleCommand {
   305  	return pb.ScheduleCommand{
   306  		UUID:        st.StoreID,
   307  		ServiceType: pb.CNService,
   308  		JoinGossipCluster: &pb.JoinGossipCluster{
   309  			Existing: st.Existing,
   310  		},
   311  	}
   312  }
   313  
   314  func deleteProxyStore(st DeleteProxyStore) pb.ScheduleCommand {
   315  	return pb.ScheduleCommand{
   316  		UUID:        st.StoreID,
   317  		ServiceType: pb.ProxyService,
   318  		DeleteProxyStore: &pb.DeleteProxyStore{
   319  			StoreID: st.StoreID,
   320  		},
   321  	}
   322  }