1 /* 2 * 3 * Copyright 2015 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H 20 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include <functional> 25 #include <iterator> 26 27 #include "absl/status/status.h" 28 #include "absl/strings/string_view.h" 29 30 #include "src/core/ext/filters/client_channel/server_address.h" 31 #include "src/core/ext/filters/client_channel/service_config.h" 32 #include "src/core/ext/filters/client_channel/subchannel_interface.h" 33 #include "src/core/lib/gprpp/orphanable.h" 34 #include "src/core/lib/gprpp/ref_counted_ptr.h" 35 #include "src/core/lib/iomgr/polling_entity.h" 36 #include "src/core/lib/iomgr/work_serializer.h" 37 #include "src/core/lib/transport/connectivity_state.h" 38 39 namespace grpc_core { 40 41 extern DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; 42 43 /// Interface for load balancing policies. 44 /// 45 /// The following concepts are used here: 46 /// 47 /// Channel: An abstraction that manages connections to backend servers 48 /// on behalf of a client application. The application creates a channel 49 /// for a given server name and then sends calls (RPCs) on it, and the 50 /// channel figures out which backend server to send each call to. A channel 51 /// contains a resolver, a load balancing policy (or a tree of LB policies), 52 /// and a set of one or more subchannels. 53 /// 54 /// Subchannel: A subchannel represents a connection to one backend server. 55 /// The LB policy decides which subchannels to create, manages the 56 /// connectivity state of those subchannels, and decides which subchannel 57 /// to send any given call to. 58 /// 59 /// Resolver: A plugin that takes a gRPC server URI and resolves it to a 60 /// list of one or more addresses and a service config, as described 61 /// in https://github.com/grpc/grpc/blob/master/doc/naming.md. See 62 /// resolver.h for the resolver API. 63 /// 64 /// Load Balancing (LB) Policy: A plugin that takes a list of addresses 65 /// from the resolver, maintains and manages a subchannel for each 66 /// backend address, and decides which subchannel to send each call on. 67 /// An LB policy has two parts: 68 /// - A LoadBalancingPolicy, which deals with the control plane work of 69 /// managing subchannels. 70 /// - A SubchannelPicker, which handles the data plane work of 71 /// determining which subchannel a given call should be sent on. 72 73 /// LoadBalacingPolicy API. 74 /// 75 /// Note: All methods with a "Locked" suffix must be called from the 76 /// work_serializer passed to the constructor. 77 /// 78 /// Any I/O done by the LB policy should be done under the pollset_set 79 /// returned by \a interested_parties(). 80 // TODO(roth): Once we move to EventManager-based polling, remove the 81 // interested_parties() hooks from the API. 82 class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> { 83 public: 84 // Represents backend metrics reported by the backend to the client. 85 struct BackendMetricData { 86 /// CPU utilization expressed as a fraction of available CPU resources. 87 double cpu_utilization; 88 /// Memory utilization expressed as a fraction of available memory 89 /// resources. 90 double mem_utilization; 91 /// Total requests per second being served by the backend. This 92 /// should include all services that a backend is responsible for. 93 uint64_t requests_per_second; 94 /// Application-specific requests cost metrics. Metric names are 95 /// determined by the application. Each value is an absolute cost 96 /// (e.g. 3487 bytes of storage) associated with the request. 97 std::map<absl::string_view, double> request_cost; 98 /// Application-specific resource utilization metrics. Metric names 99 /// are determined by the application. Each value is expressed as a 100 /// fraction of total resources available. 101 std::map<absl::string_view, double> utilization; 102 }; 103 104 /// Interface for accessing per-call state. 105 /// Implemented by the client channel and used by the SubchannelPicker. 106 class CallState { 107 public: 108 CallState() = default; 109 virtual ~CallState() = default; 110 111 /// Allocates memory associated with the call, which will be 112 /// automatically freed when the call is complete. 113 /// It is more efficient to use this than to allocate memory directly 114 /// for allocations that need to be made on a per-call basis. 115 virtual void* Alloc(size_t size) = 0; 116 117 /// Returns the backend metric data returned by the server for the call, 118 /// or null if no backend metric data was returned. 119 // TODO(roth): Move this out of CallState, since it should not be 120 // accessible to the picker, only to the recv_trailing_metadata_ready 121 // callback. It should instead be in its own interface. 122 virtual const BackendMetricData* GetBackendMetricData() = 0; 123 124 /// EXPERIMENTAL API. 125 /// Returns the value of the call attribute \a key. 126 /// Keys are static strings, so an attribute can be accessed by an LB 127 /// policy implementation only if it knows about the internal key. 128 /// Returns a null string_view if key not found. 129 virtual absl::string_view ExperimentalGetCallAttribute(const char* key) = 0; 130 }; 131 132 /// Interface for accessing metadata. 133 /// Implemented by the client channel and used by the SubchannelPicker. 134 class MetadataInterface { 135 public: 136 class iterator 137 : public std::iterator< 138 std::input_iterator_tag, 139 std::pair<absl::string_view, absl::string_view>, // value_type 140 std::ptrdiff_t, // difference_type 141 std::pair<absl::string_view, absl::string_view>*, // pointer 142 std::pair<absl::string_view, absl::string_view>& // reference 143 > { 144 public: iterator(const MetadataInterface * md,intptr_t handle)145 iterator(const MetadataInterface* md, intptr_t handle) 146 : md_(md), handle_(handle) {} 147 iterator& operator++() { 148 handle_ = md_->IteratorHandleNext(handle_); 149 return *this; 150 } 151 bool operator==(iterator other) const { 152 return md_ == other.md_ && handle_ == other.handle_; 153 } 154 bool operator!=(iterator other) const { return !(*this == other); } 155 value_type operator*() const { return md_->IteratorHandleGet(handle_); } 156 157 private: 158 friend class MetadataInterface; 159 const MetadataInterface* md_; 160 intptr_t handle_; 161 }; 162 163 virtual ~MetadataInterface() = default; 164 165 /// Adds a key/value pair. 166 /// Does NOT take ownership of \a key or \a value. 167 /// Implementations must ensure that the key and value remain alive 168 /// until the call ends. If desired, they may be allocated via 169 /// CallState::Alloc(). 170 virtual void Add(absl::string_view key, absl::string_view value) = 0; 171 172 /// Iteration interface. 173 virtual iterator begin() const = 0; 174 virtual iterator end() const = 0; 175 176 /// Removes the element pointed to by \a it. 177 /// Returns an iterator pointing to the next element. 178 virtual iterator erase(iterator it) = 0; 179 180 protected: GetIteratorHandle(const iterator & it)181 intptr_t GetIteratorHandle(const iterator& it) const { return it.handle_; } 182 183 private: 184 friend class iterator; 185 186 virtual intptr_t IteratorHandleNext(intptr_t handle) const = 0; 187 virtual std::pair<absl::string_view /*key*/, absl::string_view /*value */> 188 IteratorHandleGet(intptr_t handle) const = 0; 189 }; 190 191 /// Arguments used when picking a subchannel for a call. 192 struct PickArgs { 193 /// The path of the call. Indicates the RPC service and method name. 194 absl::string_view path; 195 /// Initial metadata associated with the picking call. 196 /// The LB policy may use the existing metadata to influence its routing 197 /// decision, and it may add new metadata elements to be sent with the 198 /// call to the chosen backend. 199 MetadataInterface* initial_metadata; 200 /// An interface for accessing call state. Can be used to allocate 201 /// memory associated with the call in an efficient way. 202 CallState* call_state; 203 }; 204 205 /// The result of picking a subchannel for a call. 206 struct PickResult { 207 enum ResultType { 208 /// Pick complete. If \a subchannel is non-null, the client channel 209 /// will immediately proceed with the call on that subchannel; 210 /// otherwise, it will drop the call. 211 PICK_COMPLETE, 212 /// Pick cannot be completed until something changes on the control 213 /// plane. The client channel will queue the pick and try again the 214 /// next time the picker is updated. 215 PICK_QUEUE, 216 /// Pick failed. If the call is wait_for_ready, the client channel 217 /// will wait for the next picker and try again; otherwise, it 218 /// will immediately fail the call with the status indicated via 219 /// \a error (although the call may be retried if the client channel 220 /// is configured to do so). 221 PICK_FAILED, 222 }; 223 ResultType type; 224 225 /// Used only if type is PICK_COMPLETE. Will be set to the selected 226 /// subchannel, or nullptr if the LB policy decides to drop the call. 227 RefCountedPtr<SubchannelInterface> subchannel; 228 229 /// Used only if type is PICK_FAILED. 230 /// Error to be set when returning a failure. 231 // TODO(roth): Replace this with something similar to grpc::Status, 232 // so that we don't expose grpc_error to this API. 233 grpc_error* error = GRPC_ERROR_NONE; 234 235 /// Used only if type is PICK_COMPLETE. 236 /// Callback set by LB policy to be notified of trailing metadata. 237 /// If set by LB policy, the client channel will invoke the callback 238 /// when trailing metadata is returned. 239 /// The metadata may be modified by the callback. However, the callback 240 /// does not take ownership, so any data that needs to be used after 241 /// returning must be copied. 242 /// The call state can be used to obtain backend metric data. 243 // TODO(roth): The arguments to this callback should be moved into a 244 // struct, so that we can later add new fields without breaking 245 // existing implementations. 246 std::function<void(grpc_error*, MetadataInterface*, CallState*)> 247 recv_trailing_metadata_ready; 248 }; 249 250 /// A subchannel picker is the object used to pick the subchannel to 251 /// use for a given call. This is implemented by the LB policy and 252 /// used by the client channel to perform picks. 253 /// 254 /// Pickers are intended to encapsulate all of the state and logic 255 /// needed on the data plane (i.e., to actually process picks for 256 /// individual calls sent on the channel) while excluding all of the 257 /// state and logic needed on the control plane (i.e., resolver 258 /// updates, connectivity state notifications, etc); the latter should 259 /// live in the LB policy object itself. 260 /// 261 /// Currently, pickers are always accessed from within the 262 /// client_channel data plane mutex, so they do not have to be 263 /// thread-safe. 264 class SubchannelPicker { 265 public: 266 SubchannelPicker() = default; 267 virtual ~SubchannelPicker() = default; 268 269 virtual PickResult Pick(PickArgs args) = 0; 270 }; 271 272 /// A proxy object implemented by the client channel and used by the 273 /// LB policy to communicate with the channel. 274 class ChannelControlHelper { 275 public: 276 ChannelControlHelper() = default; 277 virtual ~ChannelControlHelper() = default; 278 279 /// Creates a new subchannel with the specified channel args. 280 virtual RefCountedPtr<SubchannelInterface> CreateSubchannel( 281 ServerAddress address, const grpc_channel_args& args) = 0; 282 283 /// Sets the connectivity state and returns a new picker to be used 284 /// by the client channel. 285 virtual void UpdateState(grpc_connectivity_state state, 286 const absl::Status& status, 287 std::unique_ptr<SubchannelPicker>) = 0; 288 289 /// Requests that the resolver re-resolve. 290 virtual void RequestReresolution() = 0; 291 292 /// Adds a trace message associated with the channel. 293 enum TraceSeverity { TRACE_INFO, TRACE_WARNING, TRACE_ERROR }; 294 virtual void AddTraceEvent(TraceSeverity severity, 295 absl::string_view message) = 0; 296 }; 297 298 /// Interface for configuration data used by an LB policy implementation. 299 /// Individual implementations will create a subclass that adds methods to 300 /// return the parameters they need. 301 class Config : public RefCounted<Config> { 302 public: 303 ~Config() override = default; 304 305 // Returns the load balancing policy name 306 virtual const char* name() const = 0; 307 }; 308 309 /// Data passed to the UpdateLocked() method when new addresses and 310 /// config are available. 311 struct UpdateArgs { 312 ServerAddressList addresses; 313 RefCountedPtr<Config> config; 314 const grpc_channel_args* args = nullptr; 315 316 // TODO(roth): Remove everything below once channel args is 317 // converted to a copyable and movable C++ object. 318 UpdateArgs() = default; ~UpdateArgsUpdateArgs319 ~UpdateArgs() { grpc_channel_args_destroy(args); } 320 UpdateArgs(const UpdateArgs& other); 321 UpdateArgs(UpdateArgs&& other) noexcept; 322 UpdateArgs& operator=(const UpdateArgs& other); 323 UpdateArgs& operator=(UpdateArgs&& other) noexcept; 324 }; 325 326 /// Args used to instantiate an LB policy. 327 struct Args { 328 /// The work_serializer under which all LB policy calls will be run. 329 std::shared_ptr<WorkSerializer> work_serializer; 330 /// Channel control helper. 331 /// Note: LB policies MUST NOT call any method on the helper from 332 /// their constructor. 333 std::unique_ptr<ChannelControlHelper> channel_control_helper; 334 /// Channel args. 335 // TODO(roth): Find a better channel args representation for this API. 336 // TODO(roth): Clarify ownership semantics here -- currently, this 337 // does not take ownership of args, which is the opposite of how we 338 // handle them in UpdateArgs. 339 const grpc_channel_args* args = nullptr; 340 }; 341 342 explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1); 343 ~LoadBalancingPolicy() override; 344 345 // Not copyable nor movable. 346 LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; 347 LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; 348 349 /// Returns the name of the LB policy. 350 virtual const char* name() const = 0; 351 352 /// Updates the policy with new data from the resolver. Will be invoked 353 /// immediately after LB policy is constructed, and then again whenever 354 /// the resolver returns a new result. 355 virtual void UpdateLocked(UpdateArgs) = 0; // NOLINT 356 357 /// Tries to enter a READY connectivity state. 358 /// This is a no-op by default, since most LB policies never go into 359 /// IDLE state. ExitIdleLocked()360 virtual void ExitIdleLocked() {} 361 362 /// Resets connection backoff. 363 virtual void ResetBackoffLocked() = 0; 364 interested_parties()365 grpc_pollset_set* interested_parties() const { return interested_parties_; } 366 367 // Note: This must be invoked while holding the work_serializer. 368 void Orphan() override; 369 370 // A picker that returns PICK_QUEUE for all picks. 371 // Also calls the parent LB policy's ExitIdleLocked() method when the 372 // first pick is seen. 373 class QueuePicker : public SubchannelPicker { 374 public: QueuePicker(RefCountedPtr<LoadBalancingPolicy> parent)375 explicit QueuePicker(RefCountedPtr<LoadBalancingPolicy> parent) 376 : parent_(std::move(parent)) {} 377 ~QueuePicker()378 ~QueuePicker() override { parent_.reset(DEBUG_LOCATION, "QueuePicker"); } 379 380 PickResult Pick(PickArgs args) override; 381 382 private: 383 RefCountedPtr<LoadBalancingPolicy> parent_; 384 bool exit_idle_called_ = false; 385 }; 386 387 // A picker that returns PICK_TRANSIENT_FAILURE for all picks. 388 class TransientFailurePicker : public SubchannelPicker { 389 public: TransientFailurePicker(grpc_error * error)390 explicit TransientFailurePicker(grpc_error* error) : error_(error) {} ~TransientFailurePicker()391 ~TransientFailurePicker() override { GRPC_ERROR_UNREF(error_); } 392 393 PickResult Pick(PickArgs args) override; 394 395 private: 396 grpc_error* error_; 397 }; 398 399 protected: work_serializer()400 std::shared_ptr<WorkSerializer> work_serializer() const { 401 return work_serializer_; 402 } 403 404 // Note: LB policies MUST NOT call any method on the helper from their 405 // constructor. channel_control_helper()406 ChannelControlHelper* channel_control_helper() const { 407 return channel_control_helper_.get(); 408 } 409 410 /// Shuts down the policy. 411 virtual void ShutdownLocked() = 0; 412 413 private: 414 /// Work Serializer under which LB policy actions take place. 415 std::shared_ptr<WorkSerializer> work_serializer_; 416 /// Owned pointer to interested parties in load balancing decisions. 417 grpc_pollset_set* interested_parties_; 418 /// Channel control helper. 419 std::unique_ptr<ChannelControlHelper> channel_control_helper_; 420 }; 421 422 } // namespace grpc_core 423 424 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H */ 425