github.com/matrixorigin/matrixone@v1.2.0/pkg/util/cn_address_func.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 util 16 17 import ( 18 "context" 19 "math/rand" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/clusterservice" 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 "github.com/matrixorigin/matrixone/pkg/common/runtime" 25 pb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 26 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 27 ) 28 29 // HAKeeperClient is an interface which is mainly used to avoid cycle import. 30 type HAKeeperClient interface { 31 // GetClusterDetails queries the HAKeeper and return CN and TN nodes that are 32 // known to the HAKeeper. 33 GetClusterDetails(ctx context.Context) (pb.ClusterDetails, error) 34 } 35 36 func AddressFunc(getClient func() HAKeeperClient) func(context.Context, bool) (string, error) { 37 return func(ctx context.Context, random bool) (string, error) { 38 if getClient == nil || getClient() == nil { 39 return "", moerr.NewNoHAKeeper(ctx) 40 } 41 ctx, cancel := context.WithTimeout(ctx, time.Second*5) 42 defer cancel() 43 selector := clusterservice.NewSelector().SelectByLabel(nil, clusterservice.EQ) 44 if s, exist := runtime.ProcessLevelRuntime().GetGlobalVariables(runtime.BackgroundCNSelector); exist { 45 selector = s.(clusterservice.Selector) 46 } 47 details, err := getClient().GetClusterDetails(ctx) 48 if err != nil { 49 return "", err 50 } 51 cns := make([]pb.CNStore, 0, len(details.CNStores)) 52 labeled_cns := make([]pb.CNStore, 0, len(details.CNStores)) 53 for _, cn := range details.CNStores { 54 if cn.WorkState == metadata.WorkState_Working { 55 cns = append(cns, cn) 56 // get logging cn label name 57 if cn.Labels != nil && selector.Match(cn.Labels) { 58 labeled_cns = append(labeled_cns, cn) 59 } 60 } 61 } 62 if len(cns) == 0 { 63 return "", moerr.NewInvalidState(ctx, "no CN in the cluster") 64 } 65 var selectedCNs []pb.CNStore // Replace CNType with the actual type of your CNs 66 if len(labeled_cns) > 0 { 67 selectedCNs = labeled_cns 68 } else { 69 selectedCNs = cns 70 } 71 72 var n int 73 if random { 74 n = rand.Intn(len(selectedCNs)) 75 } else { 76 n = len(selectedCNs) - 1 77 } 78 79 return selectedCNs[n].SQLAddress, nil 80 81 } 82 }