github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/ctl/dist.go (about)

     1  // Copyright 2022 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package ctl
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    19  	pb "github.com/matrixorigin/matrixone/pkg/pb/ctl"
    20  	"github.com/matrixorigin/matrixone/pkg/pb/metadata"
    21  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    22  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    23  )
    24  
    25  // getDNHandlerFunc used to handle dn's debug command handle func.
    26  // method: debug command type.
    27  // whichDN: used to decide which DNs to send the debug request to, nil returned means send all dns.
    28  // payload: used to get debug command request payload
    29  // repsonseUnmarshaler: used to unmarshal response
    30  func getDNHandlerFunc(method pb.CmdMethod,
    31  	whichDN func(parameter string) ([]uint64, error),
    32  	payload func(dnShardID uint64, parameter string, proc *process.Process) ([]byte, error),
    33  	repsonseUnmarshaler func([]byte) (interface{}, error)) handleFunc {
    34  	return func(proc *process.Process,
    35  		service serviceType,
    36  		parameter string,
    37  		sender requestSender) (pb.CtlResult, error) {
    38  		if service != dn {
    39  			return pb.CtlResult{}, moerr.NewNotSupported(proc.Ctx, "service %s not supported", service)
    40  		}
    41  		targetDNs, err := whichDN(parameter)
    42  		if err != nil {
    43  			return pb.CtlResult{}, moerr.ConvertGoError(proc.Ctx, err)
    44  		}
    45  
    46  		containsDN := func(id uint64) bool {
    47  			for _, v := range targetDNs {
    48  				if v == id {
    49  					return true
    50  				}
    51  			}
    52  			return false
    53  		}
    54  
    55  		detail, err := proc.GetClusterDetails()
    56  		if err != nil {
    57  			return pb.CtlResult{}, err
    58  		}
    59  		var requests []txn.CNOpRequest
    60  		for _, store := range detail.GetDNStores() {
    61  			for _, shard := range store.Shards {
    62  				if len(targetDNs) == 0 || containsDN(shard.ShardID) {
    63  					payLoad, err := payload(shard.ShardID, parameter, proc)
    64  					if err != nil {
    65  						return pb.CtlResult{}, err
    66  					}
    67  					requests = append(requests, txn.CNOpRequest{
    68  						OpCode: uint32(method),
    69  						Target: metadata.DNShard{
    70  							DNShardRecord: metadata.DNShardRecord{
    71  								ShardID: shard.ShardID,
    72  							},
    73  							ReplicaID: shard.ReplicaID,
    74  							Address:   store.ServiceAddress,
    75  						},
    76  						Payload: payLoad,
    77  					})
    78  				}
    79  			}
    80  		}
    81  		results := make([]interface{}, 0, len(requests))
    82  		if len(requests) > 0 {
    83  			responses, err := sender(proc.Ctx, requests)
    84  			if err != nil {
    85  				return pb.CtlResult{}, err
    86  			}
    87  			if len(responses) != len(requests) {
    88  				panic("requests and response not match")
    89  			}
    90  
    91  			for _, resp := range responses {
    92  				r, err := repsonseUnmarshaler(resp.Payload)
    93  				if err != nil {
    94  					return pb.CtlResult{}, err
    95  				}
    96  				results = append(results, r)
    97  			}
    98  		}
    99  		return pb.CtlResult{Method: method.String(), Data: results}, nil
   100  	}
   101  }