68f1eb25824afcdd6ca0ff52155065520648a344
[platform/upstream/grpc.git] / src / core / ext / filters / client_channel / lb_policy.h
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 #include "absl/types/variant.h"
30
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"
39
40 namespace grpc_core {
41
42 extern DebugOnlyTraceFlag grpc_trace_lb_policy_refcount;
43
44 /// Interface for load balancing policies.
45 ///
46 /// The following concepts are used here:
47 ///
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.
54 ///
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.
59 ///
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.
64 ///
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.
73
74 /// LoadBalacingPolicy API.
75 ///
76 /// Note: All methods with a "Locked" suffix must be called from the
77 /// work_serializer passed to the constructor.
78 ///
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> {
84  public:
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
90     /// resources.
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;
103   };
104
105   /// Interface for accessing per-call state.
106   /// Implemented by the client channel and used by the SubchannelPicker.
107   class CallState {
108    public:
109     CallState() = default;
110     virtual ~CallState() = default;
111
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;
117
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;
124
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;
131   };
132
133   /// Interface for accessing metadata.
134   /// Implemented by the client channel and used by the SubchannelPicker.
135   class MetadataInterface {
136    public:
137     class iterator
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
144               > {
145      public:
146       iterator(const MetadataInterface* md, intptr_t handle)
147           : md_(md), handle_(handle) {}
148       iterator& operator++() {
149         handle_ = md_->IteratorHandleNext(handle_);
150         return *this;
151       }
152       bool operator==(iterator other) const {
153         return md_ == other.md_ && handle_ == other.handle_;
154       }
155       bool operator!=(iterator other) const { return !(*this == other); }
156       value_type operator*() const { return md_->IteratorHandleGet(handle_); }
157
158      private:
159       friend class MetadataInterface;
160       const MetadataInterface* md_;
161       intptr_t handle_;
162     };
163
164     virtual ~MetadataInterface() = default;
165
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;
172
173     /// Iteration interface.
174     virtual iterator begin() const = 0;
175     virtual iterator end() const = 0;
176
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;
180
181    protected:
182     intptr_t GetIteratorHandle(const iterator& it) const { return it.handle_; }
183
184    private:
185     friend class iterator;
186
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;
190   };
191
192   /// Arguments used when picking a subchannel for a call.
193   struct PickArgs {
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;
204   };
205
206   /// The result of picking a subchannel for a call.
207   struct PickResult {
208     /// A successful pick.
209     struct Complete {
210       /// The subchannel to be used for the call.  Must be non-null.
211       RefCountedPtr<SubchannelInterface> subchannel;
212
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;
225
226       explicit Complete(
227           RefCountedPtr<SubchannelInterface> sc,
228           std::function<void(absl::Status, MetadataInterface*, CallState*)> cb =
229               nullptr)
230           : subchannel(std::move(sc)),
231             recv_trailing_metadata_ready(std::move(cb)) {}
232     };
233
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.
237     struct Queue {};
238
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).
243     struct Fail {
244       absl::Status status;
245
246       explicit Fail(absl::Status s) : status(s) {}
247     };
248
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.
252     struct Drop {
253       absl::Status status;
254
255       explicit Drop(absl::Status s) : status(s) {}
256     };
257
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();
261
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)) {}
271   };
272
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.
276   ///
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.
283   ///
284   /// Currently, pickers are always accessed from within the
285   /// client_channel data plane mutex, so they do not have to be
286   /// thread-safe.
287   class SubchannelPicker {
288    public:
289     SubchannelPicker() = default;
290     virtual ~SubchannelPicker() = default;
291
292     virtual PickResult Pick(PickArgs args) = 0;
293   };
294
295   /// A proxy object implemented by the client channel and used by the
296   /// LB policy to communicate with the channel.
297   class ChannelControlHelper {
298    public:
299     ChannelControlHelper() = default;
300     virtual ~ChannelControlHelper() = default;
301
302     /// Creates a new subchannel with the specified channel args.
303     virtual RefCountedPtr<SubchannelInterface> CreateSubchannel(
304         ServerAddress address, const grpc_channel_args& args) = 0;
305
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;
311
312     /// Requests that the resolver re-resolve.
313     virtual void RequestReresolution() = 0;
314
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;
319   };
320
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> {
325    public:
326     ~Config() override = default;
327
328     // Returns the load balancing policy name
329     virtual const char* name() const = 0;
330   };
331
332   /// Data passed to the UpdateLocked() method when new addresses and
333   /// config are available.
334   struct UpdateArgs {
335     ServerAddressList addresses;
336     RefCountedPtr<Config> config;
337     const grpc_channel_args* args = nullptr;
338
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;
347   };
348
349   /// Args used to instantiate an LB policy.
350   struct Args {
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;
357     /// Channel args.
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;
363   };
364
365   explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1);
366   ~LoadBalancingPolicy() override;
367
368   // Not copyable nor movable.
369   LoadBalancingPolicy(const LoadBalancingPolicy&) = delete;
370   LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete;
371
372   /// Returns the name of the LB policy.
373   virtual const char* name() const = 0;
374
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
379
380   /// Tries to enter a READY connectivity state.
381   /// This is a no-op by default, since most LB policies never go into
382   /// IDLE state.
383   virtual void ExitIdleLocked() {}
384
385   /// Resets connection backoff.
386   virtual void ResetBackoffLocked() = 0;
387
388   grpc_pollset_set* interested_parties() const { return interested_parties_; }
389
390   // Note: This must be invoked while holding the work_serializer.
391   void Orphan() override;
392
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 {
397    public:
398     explicit QueuePicker(RefCountedPtr<LoadBalancingPolicy> parent)
399         : parent_(std::move(parent)) {}
400
401     ~QueuePicker() override { parent_.reset(DEBUG_LOCATION, "QueuePicker"); }
402
403     PickResult Pick(PickArgs args) override;
404
405    private:
406     RefCountedPtr<LoadBalancingPolicy> parent_;
407     bool exit_idle_called_ = false;
408   };
409
410   // A picker that returns PickResult::Fail for all picks.
411   class TransientFailurePicker : public SubchannelPicker {
412    public:
413     explicit TransientFailurePicker(absl::Status status) : status_(status) {}
414
415     PickResult Pick(PickArgs /*args*/) override {
416       return PickResult::Fail(status_);
417     }
418
419    private:
420     absl::Status status_;
421   };
422
423  protected:
424   std::shared_ptr<WorkSerializer> work_serializer() const {
425     return work_serializer_;
426   }
427
428   // Note: LB policies MUST NOT call any method on the helper from their
429   // constructor.
430   ChannelControlHelper* channel_control_helper() const {
431     return channel_control_helper_.get();
432   }
433
434   /// Shuts down the policy.
435   virtual void ShutdownLocked() = 0;
436
437  private:
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_;
444 };
445
446 }  // namespace grpc_core
447
448 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H */