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