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