Home | History | Annotate | Download | only in client_channel
      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