Imported Upstream version 1.18.0
[platform/upstream/grpc.git] / src / core / ext / filters / client_channel / subchannel.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_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 RefCounted<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   ConnectedSubchannel(
89       grpc_channel_stack* channel_stack, const grpc_channel_args* args,
90       grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
91           channelz_subchannel,
92       intptr_t socket_uuid);
93   ~ConnectedSubchannel();
94
95   void NotifyOnStateChange(grpc_pollset_set* interested_parties,
96                            grpc_connectivity_state* state,
97                            grpc_closure* closure);
98   void Ping(grpc_closure* on_initiate, grpc_closure* on_ack);
99   grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call);
100
101   grpc_channel_stack* channel_stack() const { return channel_stack_; }
102   const grpc_channel_args* args() const { return args_; }
103   channelz::SubchannelNode* channelz_subchannel() const {
104     return channelz_subchannel_.get();
105   }
106   intptr_t socket_uuid() const { return socket_uuid_; }
107
108   size_t GetInitialCallSizeEstimate(size_t parent_data_size) const;
109
110  private:
111   grpc_channel_stack* channel_stack_;
112   grpc_channel_args* args_;
113   // ref counted pointer to the channelz node in this connected subchannel's
114   // owning subchannel.
115   grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
116       channelz_subchannel_;
117   // uuid of this subchannel's socket. 0 if this subchannel is not connected.
118   const intptr_t socket_uuid_;
119 };
120
121 }  // namespace grpc_core
122
123 grpc_subchannel* grpc_subchannel_ref(
124     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
125 grpc_subchannel* grpc_subchannel_ref_from_weak_ref(
126     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
127 void grpc_subchannel_unref(
128     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
129 grpc_subchannel* grpc_subchannel_weak_ref(
130     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
131 void grpc_subchannel_weak_unref(
132     grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
133 grpc_subchannel_call* grpc_subchannel_call_ref(
134     grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
135 void grpc_subchannel_call_unref(
136     grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
137
138 grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node(
139     grpc_subchannel* subchannel);
140
141 intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel);
142
143 /** Returns a pointer to the parent data associated with \a subchannel_call.
144     The data will be of the size specified in \a parent_data_size
145     field of the args passed to \a grpc_connected_subchannel_create_call(). */
146 void* grpc_connected_subchannel_call_get_parent_data(
147     grpc_subchannel_call* subchannel_call);
148
149 /** poll the current connectivity state of a channel */
150 grpc_connectivity_state grpc_subchannel_check_connectivity(
151     grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking);
152
153 /** Calls notify when the connectivity state of a channel becomes different
154     from *state.  Updates *state with the new state of the channel. */
155 void grpc_subchannel_notify_on_state_change(
156     grpc_subchannel* channel, grpc_pollset_set* interested_parties,
157     grpc_connectivity_state* state, grpc_closure* notify,
158     bool inhibit_health_checks);
159
160 /** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected
161  * (which may happen before it initially connects or during transient failures)
162  * */
163 grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel>
164 grpc_subchannel_get_connected_subchannel(grpc_subchannel* c);
165
166 /** return the subchannel index key for \a subchannel */
167 const grpc_subchannel_key* grpc_subchannel_get_key(
168     const grpc_subchannel* subchannel);
169
170 // Resets the connection backoff of the subchannel.
171 // TODO(roth): Move connection backoff out of subchannels and up into LB
172 // policy code (probably by adding a SubchannelGroup between
173 // SubchannelList and SubchannelData), at which point this method can
174 // go away.
175 void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel);
176
177 /** continue processing a transport op */
178 void grpc_subchannel_call_process_op(grpc_subchannel_call* subchannel_call,
179                                      grpc_transport_stream_op_batch* op);
180
181 /** Must be called once per call. Sets the 'then_schedule_closure' argument for
182     call stack destruction. */
183 void grpc_subchannel_call_set_cleanup_closure(
184     grpc_subchannel_call* subchannel_call, grpc_closure* closure);
185
186 grpc_call_stack* grpc_subchannel_call_get_call_stack(
187     grpc_subchannel_call* subchannel_call);
188
189 struct grpc_subchannel_args {
190   /* When updating this struct, also update subchannel_index.c */
191
192   /** Channel filters for this channel - wrapped factories will likely
193       want to mutate this */
194   const grpc_channel_filter** filters;
195   /** The number of filters in the above array */
196   size_t filter_count;
197   /** Channel arguments to be supplied to the newly created channel */
198   const grpc_channel_args* args;
199 };
200
201 /** create a subchannel given a connector */
202 grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
203                                         const grpc_subchannel_args* args);
204
205 /// Sets \a addr from \a args.
206 void grpc_get_subchannel_address_arg(const grpc_channel_args* args,
207                                      grpc_resolved_address* addr);
208
209 const char* grpc_subchannel_get_target(grpc_subchannel* subchannel);
210
211 /// Returns the URI string for the address to connect to.
212 const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args);
213
214 /// Returns a new channel arg encoding the subchannel address as a string.
215 /// Caller is responsible for freeing the string.
216 grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr);
217
218 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H */