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_SUBCHANNEL_H 20 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_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/connector.h" 26 #include "src/core/lib/channel/channel_stack.h" 27 #include "src/core/lib/gpr/arena.h" 28 #include "src/core/lib/gprpp/ref_counted.h" 29 #include "src/core/lib/gprpp/ref_counted_ptr.h" 30 #include "src/core/lib/iomgr/polling_entity.h" 31 #include "src/core/lib/transport/connectivity_state.h" 32 #include "src/core/lib/transport/metadata.h" 33 34 // Channel arg containing a grpc_resolved_address to connect to. 35 #define GRPC_ARG_SUBCHANNEL_ADDRESS "grpc.subchannel_address" 36 37 /** A (sub-)channel that knows how to connect to exactly one target 38 address. Provides a target for load balancing. */ 39 typedef struct grpc_subchannel grpc_subchannel; 40 typedef struct grpc_subchannel_call grpc_subchannel_call; 41 typedef struct grpc_subchannel_args grpc_subchannel_args; 42 typedef struct grpc_subchannel_key grpc_subchannel_key; 43 44 #ifndef NDEBUG 45 #define GRPC_SUBCHANNEL_REF(p, r) \ 46 grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) 47 #define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ 48 grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r)) 49 #define GRPC_SUBCHANNEL_UNREF(p, r) \ 50 grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) 51 #define GRPC_SUBCHANNEL_WEAK_REF(p, r) \ 52 grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) 53 #define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \ 54 grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r)) 55 #define GRPC_SUBCHANNEL_CALL_REF(p, r) \ 56 grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) 57 #define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \ 58 grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) 59 #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ 60 , const char *file, int line, const char *reason 61 #else 62 #define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) 63 #define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ 64 grpc_subchannel_ref_from_weak_ref((p)) 65 #define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) 66 #define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) 67 #define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p)) 68 #define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) 69 #define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p)) 70 #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS 71 #endif 72 73 namespace grpc_core { 74 75 class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> { 76 public: 77 struct CallArgs { 78 grpc_polling_entity* pollent; 79 grpc_slice path; 80 gpr_timespec start_time; 81 grpc_millis deadline; 82 gpr_arena* arena; 83 grpc_call_context_element* context; 84 grpc_call_combiner* call_combiner; 85 size_t parent_data_size; 86 }; 87 88 explicit ConnectedSubchannel(grpc_channel_stack* channel_stack, 89 channelz::SubchannelNode* channelz_subchannel); 90 ~ConnectedSubchannel(); 91 92 grpc_channel_stack* channel_stack() { return channel_stack_; } 93 void NotifyOnStateChange(grpc_pollset_set* interested_parties, 94 grpc_connectivity_state* state, 95 grpc_closure* closure); 96 void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); 97 grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); 98 channelz::SubchannelNode* channelz_subchannel() { 99 return channelz_subchannel_; 100 } 101 102 private: 103 grpc_channel_stack* channel_stack_; 104 // backpointer to the channelz node in this connected subchannel's 105 // owning subchannel. 106 channelz::SubchannelNode* channelz_subchannel_; 107 }; 108 109 } // namespace grpc_core 110 111 grpc_subchannel* grpc_subchannel_ref( 112 grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 113 grpc_subchannel* grpc_subchannel_ref_from_weak_ref( 114 grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 115 void grpc_subchannel_unref( 116 grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 117 grpc_subchannel* grpc_subchannel_weak_ref( 118 grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 119 void grpc_subchannel_weak_unref( 120 grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 121 grpc_subchannel_call* grpc_subchannel_call_ref( 122 grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 123 void grpc_subchannel_call_unref( 124 grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); 125 126 grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( 127 grpc_subchannel* subchannel); 128 129 /** Returns a pointer to the parent data associated with \a subchannel_call. 130 The data will be of the size specified in \a parent_data_size 131 field of the args passed to \a grpc_connected_subchannel_create_call(). */ 132 void* grpc_connected_subchannel_call_get_parent_data( 133 grpc_subchannel_call* subchannel_call); 134 135 /** poll the current connectivity state of a channel */ 136 grpc_connectivity_state grpc_subchannel_check_connectivity( 137 grpc_subchannel* channel, grpc_error** error); 138 139 /** Calls notify when the connectivity state of a channel becomes different 140 from *state. Updates *state with the new state of the channel. */ 141 void grpc_subchannel_notify_on_state_change( 142 grpc_subchannel* channel, grpc_pollset_set* interested_parties, 143 grpc_connectivity_state* state, grpc_closure* notify); 144 145 /** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected 146 * (which may happen before it initially connects or during transient failures) 147 * */ 148 grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> 149 grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); 150 151 /** return the subchannel index key for \a subchannel */ 152 const grpc_subchannel_key* grpc_subchannel_get_key( 153 const grpc_subchannel* subchannel); 154 155 // Resets the connection backoff of the subchannel. 156 // TODO(roth): Move connection backoff out of subchannels and up into LB 157 // policy code (probably by adding a SubchannelGroup between 158 // SubchannelList and SubchannelData), at which point this method can 159 // go away. 160 void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel); 161 162 /** continue processing a transport op */ 163 void grpc_subchannel_call_process_op(grpc_subchannel_call* subchannel_call, 164 grpc_transport_stream_op_batch* op); 165 166 /** Must be called once per call. Sets the 'then_schedule_closure' argument for 167 call stack destruction. */ 168 void grpc_subchannel_call_set_cleanup_closure( 169 grpc_subchannel_call* subchannel_call, grpc_closure* closure); 170 171 grpc_call_stack* grpc_subchannel_call_get_call_stack( 172 grpc_subchannel_call* subchannel_call); 173 174 struct grpc_subchannel_args { 175 /* When updating this struct, also update subchannel_index.c */ 176 177 /** Channel filters for this channel - wrapped factories will likely 178 want to mutate this */ 179 const grpc_channel_filter** filters; 180 /** The number of filters in the above array */ 181 size_t filter_count; 182 /** Channel arguments to be supplied to the newly created channel */ 183 const grpc_channel_args* args; 184 }; 185 186 /** create a subchannel given a connector */ 187 grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, 188 const grpc_subchannel_args* args); 189 190 /// Sets \a addr from \a args. 191 void grpc_get_subchannel_address_arg(const grpc_channel_args* args, 192 grpc_resolved_address* addr); 193 194 const char* grpc_subchannel_get_target(grpc_subchannel* subchannel); 195 196 /// Returns the URI string for the address to connect to. 197 const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args); 198 199 /// Returns a new channel arg encoding the subchannel address as a string. 200 /// Caller is responsible for freeing the string. 201 grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr); 202 203 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H */ 204