• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/core/ext/filters/client_channel/client_channel_channelz.h"
25 #include "src/core/ext/filters/client_channel/client_channel_factory.h"
26 #include "src/core/ext/filters/client_channel/subchannel.h"
27 #include "src/core/lib/gprpp/abstract.h"
28 #include "src/core/lib/gprpp/orphanable.h"
29 #include "src/core/lib/gprpp/ref_counted_ptr.h"
30 #include "src/core/lib/iomgr/combiner.h"
31 #include "src/core/lib/iomgr/polling_entity.h"
32 #include "src/core/lib/transport/connectivity_state.h"
33 
34 extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount;
35 
36 namespace grpc_core {
37 
38 /// Interface for load balancing policies.
39 ///
40 /// Note: All methods with a "Locked" suffix must be called from the
41 /// combiner passed to the constructor.
42 ///
43 /// Any I/O done by the LB policy should be done under the pollset_set
44 /// returned by \a interested_parties().
45 class LoadBalancingPolicy
46     : public InternallyRefCountedWithTracing<LoadBalancingPolicy> {
47  public:
48   struct Args {
49     /// The combiner under which all LB policy calls will be run.
50     /// Policy does NOT take ownership of the reference to the combiner.
51     // TODO(roth): Once we have a C++-like interface for combiners, this
52     // API should change to take a smart pointer that does pass ownership
53     // of a reference.
54     grpc_combiner* combiner = nullptr;
55     /// Used to create channels and subchannels.
56     grpc_client_channel_factory* client_channel_factory = nullptr;
57     /// Channel args from the resolver.
58     /// Note that the LB policy gets the set of addresses from the
59     /// GRPC_ARG_LB_ADDRESSES channel arg.
60     grpc_channel_args* args = nullptr;
61   };
62 
63   /// State used for an LB pick.
64   struct PickState {
65     /// Initial metadata associated with the picking call.
66     grpc_metadata_batch* initial_metadata;
67     /// Bitmask used for selective cancelling. See
68     /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in
69     /// grpc_types.h.
70     uint32_t initial_metadata_flags;
71     /// Storage for LB token in \a initial_metadata, or nullptr if not used.
72     grpc_linked_mdelem lb_token_mdelem_storage;
73     /// Closure to run when pick is complete, if not completed synchronously.
74     /// If null, pick will fail if a result is not available synchronously.
75     grpc_closure* on_complete;
76     /// Will be set to the selected subchannel, or nullptr on failure or when
77     /// the LB policy decides to drop the call.
78     RefCountedPtr<ConnectedSubchannel> connected_subchannel;
79     /// Will be populated with context to pass to the subchannel call, if
80     /// needed.
81     grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT];
82     /// Upon success, \a *user_data will be set to whatever opaque information
83     /// may need to be propagated from the LB policy, or nullptr if not needed.
84     // TODO(roth): As part of revamping our metadata APIs, try to find a
85     // way to clean this up and C++-ify it.
86     void** user_data;
87     /// Next pointer.  For internal use by LB policy.
88     PickState* next;
89   };
90 
91   // Not copyable nor movable.
92   LoadBalancingPolicy(const LoadBalancingPolicy&) = delete;
93   LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete;
94 
95   /// Updates the policy with a new set of \a args from the resolver.
96   /// Note that the LB policy gets the set of addresses from the
97   /// GRPC_ARG_LB_ADDRESSES channel arg.
98   virtual void UpdateLocked(const grpc_channel_args& args) GRPC_ABSTRACT;
99 
100   /// Finds an appropriate subchannel for a call, based on data in \a pick.
101   /// \a pick must remain alive until the pick is complete.
102   ///
103   /// If a result is known immediately, returns true, setting \a *error
104   /// upon failure.  Otherwise, \a pick->on_complete will be invoked once
105   /// the pick is complete with its error argument set to indicate success
106   /// or failure.
107   ///
108   /// If \a pick->on_complete is null and no result is known immediately,
109   /// a synchronous failure will be returned (i.e., \a *error will be
110   /// set and true will be returned).
111   virtual bool PickLocked(PickState* pick, grpc_error** error) GRPC_ABSTRACT;
112 
113   /// Cancels \a pick.
114   /// The \a on_complete callback of the pending pick will be invoked with
115   /// \a pick->connected_subchannel set to null.
116   virtual void CancelPickLocked(PickState* pick,
117                                 grpc_error* error) GRPC_ABSTRACT;
118 
119   /// Cancels all pending picks for which their \a initial_metadata_flags (as
120   /// given in the call to \a PickLocked()) matches
121   /// \a initial_metadata_flags_eq when ANDed with
122   /// \a initial_metadata_flags_mask.
123   virtual void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
124                                          uint32_t initial_metadata_flags_eq,
125                                          grpc_error* error) GRPC_ABSTRACT;
126 
127   /// Requests a notification when the connectivity state of the policy
128   /// changes from \a *state.  When that happens, sets \a *state to the
129   /// new state and schedules \a closure.
130   virtual void NotifyOnStateChangeLocked(grpc_connectivity_state* state,
131                                          grpc_closure* closure) GRPC_ABSTRACT;
132 
133   /// Returns the policy's current connectivity state.  Sets \a error to
134   /// the associated error, if any.
135   virtual grpc_connectivity_state CheckConnectivityLocked(
136       grpc_error** connectivity_error) GRPC_ABSTRACT;
137 
138   /// Hands off pending picks to \a new_policy.
139   virtual void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy)
140       GRPC_ABSTRACT;
141 
142   /// Tries to enter a READY connectivity state.
143   /// TODO(roth): As part of restructuring how we handle IDLE state,
144   /// consider whether this method is still needed.
145   virtual void ExitIdleLocked() GRPC_ABSTRACT;
146 
147   /// Resets connection backoff.
148   virtual void ResetBackoffLocked() GRPC_ABSTRACT;
149 
150   /// Populates child_subchannels and child_channels with the uuids of this
151   /// LB policy's referenced children. This is not invoked from the
152   /// client_channel's combiner. The implementation is responsible for
153   /// providing its own synchronization.
154   virtual void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
155                                         ChildRefsList* child_channels)
156       GRPC_ABSTRACT;
157 
Orphan()158   void Orphan() override {
159     // Invoke ShutdownAndUnrefLocked() inside of the combiner.
160     GRPC_CLOSURE_SCHED(
161         GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this,
162                             grpc_combiner_scheduler(combiner_)),
163         GRPC_ERROR_NONE);
164   }
165 
166   /// Sets the re-resolution closure to \a request_reresolution.
SetReresolutionClosureLocked(grpc_closure * request_reresolution)167   void SetReresolutionClosureLocked(grpc_closure* request_reresolution) {
168     GPR_ASSERT(request_reresolution_ == nullptr);
169     request_reresolution_ = request_reresolution;
170   }
171 
interested_parties()172   grpc_pollset_set* interested_parties() const { return interested_parties_; }
173 
174   GRPC_ABSTRACT_BASE_CLASS
175 
176  protected:
177   GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
178 
179   explicit LoadBalancingPolicy(const Args& args);
180   virtual ~LoadBalancingPolicy();
181 
combiner()182   grpc_combiner* combiner() const { return combiner_; }
client_channel_factory()183   grpc_client_channel_factory* client_channel_factory() const {
184     return client_channel_factory_;
185   }
186 
187   /// Shuts down the policy.  Any pending picks that have not been
188   /// handed off to a new policy via HandOffPendingPicksLocked() will be
189   /// failed.
190   virtual void ShutdownLocked() GRPC_ABSTRACT;
191 
192   /// Tries to request a re-resolution.
193   void TryReresolutionLocked(grpc_core::TraceFlag* grpc_lb_trace,
194                              grpc_error* error);
195 
196  private:
ShutdownAndUnrefLocked(void * arg,grpc_error * ignored)197   static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) {
198     LoadBalancingPolicy* policy = static_cast<LoadBalancingPolicy*>(arg);
199     policy->ShutdownLocked();
200     policy->Unref();
201   }
202 
203   /// Combiner under which LB policy actions take place.
204   grpc_combiner* combiner_;
205   /// Client channel factory, used to create channels and subchannels.
206   grpc_client_channel_factory* client_channel_factory_;
207   /// Owned pointer to interested parties in load balancing decisions.
208   grpc_pollset_set* interested_parties_;
209   /// Callback to force a re-resolution.
210   grpc_closure* request_reresolution_;
211 
212   // Dummy classes needed for alignment issues.
213   // See https://github.com/grpc/grpc/issues/16032 for context.
214   // TODO(ncteisen): remove this as soon as the issue is resolved.
215   ChildRefsList dummy_list_foo;
216   ChildRefsList dummy_list_bar;
217 };
218 
219 }  // namespace grpc_core
220 
221 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H */
222