vitess.io/vitess@v0.16.2/go/vt/vtorc/logic/keyspace_discovery.go (about)

     1  /*
     2  Copyright 2022 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package logic
    18  
    19  import (
    20  	"context"
    21  	"sort"
    22  	"strings"
    23  	"sync"
    24  
    25  	"vitess.io/vitess/go/vt/log"
    26  
    27  	"vitess.io/vitess/go/vt/topo"
    28  	"vitess.io/vitess/go/vt/vtorc/inst"
    29  )
    30  
    31  // RefreshAllKeyspaces reloads the keyspace information for the keyspaces that vtorc is concerned with.
    32  func RefreshAllKeyspaces() {
    33  	var keyspaces []string
    34  	if len(clustersToWatch) == 0 { // all known keyspaces
    35  		ctx, cancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout)
    36  		defer cancel()
    37  		var err error
    38  		// Get all the keyspaces
    39  		keyspaces, err = ts.GetKeyspaces(ctx)
    40  		if err != nil {
    41  			log.Error(err)
    42  			return
    43  		}
    44  	} else {
    45  		// Parse input and build list of keyspaces
    46  		for _, ks := range clustersToWatch {
    47  			if strings.Contains(ks, "/") {
    48  				// This is a keyspace/shard specification
    49  				input := strings.Split(ks, "/")
    50  				keyspaces = append(keyspaces, input[0])
    51  			} else {
    52  				// Assume this is a keyspace
    53  				keyspaces = append(keyspaces, ks)
    54  			}
    55  		}
    56  		if len(keyspaces) == 0 {
    57  			log.Errorf("Found no keyspaces for input: %+v", clustersToWatch)
    58  			return
    59  		}
    60  	}
    61  
    62  	// Sort the list of keyspaces.
    63  	// The list can have duplicates because the input to clusters to watch may have multiple shards of the same keyspace
    64  	sort.Strings(keyspaces)
    65  	refreshCtx, refreshCancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout)
    66  	defer refreshCancel()
    67  	var wg sync.WaitGroup
    68  	for idx, keyspace := range keyspaces {
    69  		// Check if the current keyspace name is the same as the last one.
    70  		// If it is, then we know we have already refreshed its information.
    71  		// We do not need to do it again.
    72  		if idx != 0 && keyspace == keyspaces[idx-1] {
    73  			continue
    74  		}
    75  		wg.Add(1)
    76  		go func(keyspace string) {
    77  			defer wg.Done()
    78  			_ = refreshKeyspace(refreshCtx, keyspace)
    79  		}(keyspace)
    80  	}
    81  	wg.Wait()
    82  }
    83  
    84  // RefreshKeyspace refreshes the keyspace's information for the given keyspace from the topo
    85  func RefreshKeyspace(keyspaceName string) error {
    86  	refreshCtx, refreshCancel := context.WithTimeout(context.Background(), topo.RemoteOperationTimeout)
    87  	defer refreshCancel()
    88  	return refreshKeyspace(refreshCtx, keyspaceName)
    89  }
    90  
    91  // refreshKeyspace is a helper function which reloads the given keyspace's information
    92  func refreshKeyspace(ctx context.Context, keyspaceName string) error {
    93  	keyspaceInfo, err := ts.GetKeyspace(ctx, keyspaceName)
    94  	if err != nil {
    95  		log.Error(err)
    96  		return err
    97  	}
    98  	err = inst.SaveKeyspace(keyspaceInfo)
    99  	if err != nil {
   100  		log.Error(err)
   101  	}
   102  	return err
   103  }