vitess.io/vitess@v0.16.2/go/vt/srvtopo/discover.go (about) 1 /* 2 Copyright 2019 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 srvtopo 18 19 import ( 20 "sync" 21 22 "context" 23 24 "vitess.io/vitess/go/vt/concurrency" 25 "vitess.io/vitess/go/vt/log" 26 "vitess.io/vitess/go/vt/topo" 27 28 querypb "vitess.io/vitess/go/vt/proto/query" 29 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 30 ) 31 32 // FindAllTargets goes through all serving shards in the topology 33 // for the provided tablet types. It returns one Target object per 34 // keyspace / shard / matching TabletType. 35 func FindAllTargets(ctx context.Context, ts Server, cell string, tabletTypes []topodatapb.TabletType) ([]*querypb.Target, error) { 36 ksNames, err := ts.GetSrvKeyspaceNames(ctx, cell, true) 37 if err != nil { 38 return nil, err 39 } 40 41 var targets []*querypb.Target 42 var wg sync.WaitGroup 43 var mu sync.Mutex 44 var errRecorder concurrency.AllErrorRecorder 45 for _, ksName := range ksNames { 46 wg.Add(1) 47 go func(keyspace string) { 48 defer wg.Done() 49 50 // Get SrvKeyspace for cell/keyspace. 51 ks, err := ts.GetSrvKeyspace(ctx, cell, keyspace) 52 if err != nil { 53 if topo.IsErrType(err, topo.NoNode) { 54 // Possibly a race condition, or leftover 55 // crud in the topology service. Just log it. 56 log.Warningf("GetSrvKeyspace(%v, %v) returned ErrNoNode, skipping that SrvKeyspace", cell, keyspace) 57 } else { 58 // More serious error, abort. 59 errRecorder.RecordError(err) 60 } 61 return 62 } 63 64 // Get all shard names that are used for serving. 65 for _, ksPartition := range ks.Partitions { 66 // Check we're waiting for tablets of that type. 67 waitForIt := false 68 for _, tt := range tabletTypes { 69 if tt == ksPartition.ServedType { 70 waitForIt = true 71 } 72 } 73 if !waitForIt { 74 continue 75 } 76 77 // Add all the shards. Note we can't have 78 // duplicates, as there is only one entry per 79 // TabletType in the Partitions list. 80 mu.Lock() 81 for _, shard := range ksPartition.ShardReferences { 82 targets = append(targets, &querypb.Target{ 83 Cell: cell, 84 Keyspace: keyspace, 85 Shard: shard.Name, 86 TabletType: ksPartition.ServedType, 87 }) 88 } 89 mu.Unlock() 90 } 91 }(ksName) 92 } 93 wg.Wait() 94 if errRecorder.HasErrors() { 95 return nil, errRecorder.Error() 96 } 97 98 return targets, nil 99 }