1 // 2 // 3 // Copyright 2018 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPC_SRC_CORE_RESOLVER_ENDPOINT_ADDRESSES_H 20 #define GRPC_SRC_CORE_RESOLVER_ENDPOINT_ADDRESSES_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <set> 25 #include <string> 26 #include <utility> 27 #include <vector> 28 29 #include "absl/functional/function_ref.h" 30 31 #include "src/core/lib/channel/channel_args.h" 32 #include "src/core/lib/iomgr/resolved_address.h" 33 34 // A channel arg key prefix used for args that are intended to be used 35 // only internally to resolvers and LB policies and should not be part 36 // of the subchannel key. The channel will automatically filter out any 37 // args with this prefix from the subchannel's args. 38 #define GRPC_ARG_NO_SUBCHANNEL_PREFIX "grpc.internal.no_subchannel." 39 40 // A channel arg indicating the weight of an address. 41 #define GRPC_ARG_ADDRESS_WEIGHT GRPC_ARG_NO_SUBCHANNEL_PREFIX "address.weight" 42 43 namespace grpc_core { 44 45 // A list of addresses for a given endpoint with an associated set of channel 46 // args. Any args present here will be merged into the channel args when a 47 // subchannel is created for each address. 48 class EndpointAddresses final { 49 public: 50 // For backward compatibility. 51 // TODO(roth): Remove when callers have been updated. 52 EndpointAddresses(const grpc_resolved_address& address, 53 const ChannelArgs& args); 54 55 // addresses must not be empty. 56 EndpointAddresses(std::vector<grpc_resolved_address> addresses, 57 const ChannelArgs& args); 58 59 // Copyable. 60 EndpointAddresses(const EndpointAddresses& other); 61 EndpointAddresses& operator=(const EndpointAddresses& other); 62 63 // Movable. 64 EndpointAddresses(EndpointAddresses&& other) noexcept; 65 EndpointAddresses& operator=(EndpointAddresses&& other) noexcept; 66 67 bool operator==(const EndpointAddresses& other) const { 68 return Cmp(other) == 0; 69 } 70 bool operator!=(const EndpointAddresses& other) const { 71 return Cmp(other) != 0; 72 } 73 bool operator<(const EndpointAddresses& other) const { 74 return Cmp(other) < 0; 75 } 76 77 int Cmp(const EndpointAddresses& other) const; 78 79 // For backward compatibility only. 80 // TODO(roth): Remove when all callers have been updated. address()81 const grpc_resolved_address& address() const { return addresses_[0]; } 82 addresses()83 const std::vector<grpc_resolved_address>& addresses() const { 84 return addresses_; 85 } args()86 const ChannelArgs& args() const { return args_; } 87 88 // TODO(ctiller): Prior to making this a public API we should ensure that the 89 // channel args are not part of the generated string, lest we make that debug 90 // format load-bearing via Hyrum's law. 91 std::string ToString() const; 92 93 private: 94 std::vector<grpc_resolved_address> addresses_; 95 ChannelArgs args_; 96 }; 97 98 using EndpointAddressesList = std::vector<EndpointAddresses>; 99 100 struct ResolvedAddressLessThan { 101 bool operator()(const grpc_resolved_address& addr1, 102 const grpc_resolved_address& addr2) const; 103 }; 104 105 class EndpointAddressSet final { 106 public: EndpointAddressSet(const std::vector<grpc_resolved_address> & addresses)107 explicit EndpointAddressSet( 108 const std::vector<grpc_resolved_address>& addresses) 109 : addresses_(addresses.begin(), addresses.end()) {} 110 111 bool operator==(const EndpointAddressSet& other) const; 112 bool operator<(const EndpointAddressSet& other) const; 113 114 std::string ToString() const; 115 116 private: 117 std::set<grpc_resolved_address, ResolvedAddressLessThan> addresses_; 118 }; 119 120 // An iterator interface for endpoints. 121 class EndpointAddressesIterator { 122 public: 123 virtual ~EndpointAddressesIterator() = default; 124 125 // Invokes callback once for each endpoint. 126 virtual void ForEach( 127 absl::FunctionRef<void(const EndpointAddresses&)> callback) const = 0; 128 }; 129 130 // Iterator over a fixed list of endpoints. 131 class EndpointAddressesListIterator final : public EndpointAddressesIterator { 132 public: EndpointAddressesListIterator(EndpointAddressesList endpoints)133 explicit EndpointAddressesListIterator(EndpointAddressesList endpoints) 134 : endpoints_(std::move(endpoints)) {} 135 ForEach(absl::FunctionRef<void (const EndpointAddresses &)> callback)136 void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback) 137 const override { 138 for (const auto& endpoint : endpoints_) { 139 callback(endpoint); 140 } 141 } 142 143 private: 144 EndpointAddressesList endpoints_; 145 }; 146 147 // Iterator that returns only a single endpoint. 148 class SingleEndpointIterator final : public EndpointAddressesIterator { 149 public: SingleEndpointIterator(EndpointAddresses endpoint)150 explicit SingleEndpointIterator(EndpointAddresses endpoint) 151 : endpoint_(std::move(endpoint)) {} 152 ForEach(absl::FunctionRef<void (const EndpointAddresses &)> callback)153 void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback) 154 const override { 155 callback(endpoint_); 156 } 157 158 private: 159 EndpointAddresses endpoint_; 160 }; 161 162 } // namespace grpc_core 163 164 #endif // GRPC_SRC_CORE_RESOLVER_ENDPOINT_ADDRESSES_H 165