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 }