grpc 1.22.0 → 1.23.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +487 -649
  3. data/include/grpc/grpc_security.h +25 -0
  4. data/include/grpc/impl/codegen/grpc_types.h +11 -2
  5. data/include/grpc/impl/codegen/port_platform.h +12 -0
  6. data/src/core/ext/filters/client_channel/backup_poller.cc +4 -2
  7. data/src/core/ext/filters/client_channel/client_channel.cc +477 -182
  8. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +25 -16
  9. data/src/core/ext/filters/client_channel/client_channel_channelz.h +11 -6
  10. data/src/core/ext/filters/client_channel/connector.h +10 -2
  11. data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -3
  12. data/src/core/ext/filters/client_channel/http_proxy.cc +9 -10
  13. data/src/core/ext/filters/client_channel/lb_policy.cc +2 -17
  14. data/src/core/ext/filters/client_channel/lb_policy.h +36 -8
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +22 -8
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +86 -52
  17. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h +7 -0
  18. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +73 -72
  19. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +8 -12
  20. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +25 -101
  21. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +5 -5
  22. data/src/core/ext/filters/client_channel/parse_address.cc +29 -26
  23. data/src/core/ext/filters/client_channel/resolver.h +3 -11
  24. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +5 -3
  25. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +405 -82
  26. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +44 -51
  27. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +0 -1
  28. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +0 -1
  29. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +11 -6
  30. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +130 -65
  31. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +8 -3
  32. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +31 -14
  33. data/src/core/ext/filters/client_channel/resolver_factory.h +4 -0
  34. data/src/core/ext/filters/client_channel/resolver_registry.cc +11 -0
  35. data/src/core/ext/filters/client_channel/resolver_registry.h +3 -0
  36. data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +10 -49
  37. data/src/core/ext/filters/client_channel/resolving_lb_policy.h +1 -14
  38. data/src/core/ext/filters/client_channel/retry_throttle.h +2 -3
  39. data/src/core/ext/filters/client_channel/subchannel.cc +65 -58
  40. data/src/core/ext/filters/client_channel/subchannel.h +65 -45
  41. data/src/core/ext/filters/client_channel/subchannel_interface.h +15 -30
  42. data/src/core/ext/filters/client_idle/client_idle_filter.cc +262 -0
  43. data/src/core/ext/filters/http/client/http_client_filter.cc +4 -5
  44. data/src/core/ext/filters/http/client_authority_filter.cc +2 -2
  45. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +140 -152
  46. data/src/core/ext/filters/max_age/max_age_filter.cc +3 -3
  47. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +3 -4
  48. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +7 -6
  49. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +63 -38
  50. data/src/core/ext/transport/chttp2/transport/context_list.cc +3 -1
  51. data/src/core/ext/transport/chttp2/transport/frame_data.cc +4 -4
  52. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +1 -1
  53. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -0
  55. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +7 -0
  56. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +1 -0
  57. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +37 -22
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +136 -81
  59. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -0
  60. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -166
  61. data/src/core/ext/transport/chttp2/transport/hpack_table.h +41 -15
  62. data/src/core/ext/transport/chttp2/transport/internal.h +13 -2
  63. data/src/core/ext/transport/chttp2/transport/parsing.cc +35 -22
  64. data/src/core/ext/transport/chttp2/transport/stream_map.cc +28 -18
  65. data/src/core/ext/transport/chttp2/transport/writing.cc +1 -0
  66. data/src/core/ext/transport/inproc/inproc_transport.cc +1 -1
  67. data/src/core/lib/channel/channelz.cc +80 -33
  68. data/src/core/lib/channel/channelz.h +28 -13
  69. data/src/core/lib/compression/compression.cc +1 -2
  70. data/src/core/lib/compression/compression_args.cc +13 -6
  71. data/src/core/lib/compression/compression_args.h +3 -2
  72. data/src/core/lib/compression/compression_internal.cc +1 -1
  73. data/src/core/lib/gpr/env_linux.cc +10 -21
  74. data/src/core/lib/gpr/env_posix.cc +0 -5
  75. data/src/core/lib/gpr/string.cc +7 -2
  76. data/src/core/lib/gpr/string.h +1 -0
  77. data/src/core/lib/gpr/sync_posix.cc +0 -129
  78. data/src/core/lib/gprpp/debug_location.h +3 -2
  79. data/src/core/lib/gprpp/fork.cc +14 -21
  80. data/src/core/lib/gprpp/fork.h +15 -4
  81. data/src/core/lib/gprpp/host_port.cc +118 -0
  82. data/src/core/lib/{gpr → gprpp}/host_port.h +27 -11
  83. data/src/core/lib/gprpp/map.h +25 -0
  84. data/src/core/lib/gprpp/memory.h +26 -9
  85. data/src/core/lib/gprpp/ref_counted.h +63 -21
  86. data/src/core/lib/gprpp/string_view.h +143 -0
  87. data/src/core/lib/gprpp/thd.h +10 -1
  88. data/src/core/lib/gprpp/thd_posix.cc +25 -0
  89. data/src/core/lib/gprpp/thd_windows.cc +9 -1
  90. data/src/core/lib/http/httpcli_security_connector.cc +3 -1
  91. data/src/core/lib/iomgr/cfstream_handle.cc +6 -1
  92. data/src/core/lib/iomgr/cfstream_handle.h +8 -2
  93. data/src/core/lib/iomgr/combiner.cc +4 -4
  94. data/src/core/lib/iomgr/error.cc +18 -8
  95. data/src/core/lib/iomgr/error.h +2 -0
  96. data/src/core/lib/iomgr/ev_posix.cc +4 -2
  97. data/src/core/lib/iomgr/executor.cc +4 -1
  98. data/src/core/lib/iomgr/executor/mpmcqueue.cc +183 -0
  99. data/src/core/lib/iomgr/executor/mpmcqueue.h +178 -0
  100. data/src/core/lib/iomgr/executor/threadpool.cc +138 -0
  101. data/src/core/lib/iomgr/executor/threadpool.h +153 -0
  102. data/src/core/lib/iomgr/fork_posix.cc +4 -2
  103. data/src/core/lib/iomgr/iocp_windows.cc +2 -2
  104. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +14 -0
  105. data/src/core/lib/iomgr/iomgr_uv.cc +3 -0
  106. data/src/core/lib/iomgr/lockfree_event.cc +3 -3
  107. data/src/core/lib/iomgr/resolve_address_custom.cc +16 -20
  108. data/src/core/lib/iomgr/resolve_address_posix.cc +8 -10
  109. data/src/core/lib/iomgr/resolve_address_windows.cc +6 -8
  110. data/src/core/lib/iomgr/sockaddr_utils.cc +5 -3
  111. data/src/core/lib/iomgr/socket_utils_common_posix.cc +0 -1
  112. data/src/core/lib/iomgr/socket_windows.h +1 -1
  113. data/src/core/lib/iomgr/tcp_client_cfstream.cc +7 -6
  114. data/src/core/lib/iomgr/tcp_client_custom.cc +1 -0
  115. data/src/core/lib/iomgr/tcp_custom.cc +4 -0
  116. data/src/core/lib/iomgr/tcp_posix.cc +8 -2
  117. data/src/core/lib/iomgr/tcp_server_custom.cc +1 -0
  118. data/src/core/lib/iomgr/tcp_server_windows.cc +1 -1
  119. data/src/core/lib/iomgr/tcp_windows.cc +7 -7
  120. data/src/core/lib/iomgr/timer_custom.cc +1 -0
  121. data/src/core/lib/iomgr/timer_manager.cc +0 -29
  122. data/src/core/lib/security/credentials/credentials.cc +84 -0
  123. data/src/core/lib/security/credentials/credentials.h +58 -2
  124. data/src/core/lib/security/credentials/jwt/json_token.cc +6 -2
  125. data/src/core/lib/security/credentials/jwt/json_token.h +1 -1
  126. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +245 -24
  127. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +16 -0
  128. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +3 -2
  129. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +21 -25
  130. data/src/core/lib/security/security_connector/local/local_security_connector.cc +3 -2
  131. data/src/core/lib/security/security_connector/security_connector.cc +1 -1
  132. data/src/core/lib/security/security_connector/security_connector.h +1 -1
  133. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +19 -19
  134. data/src/core/lib/security/security_connector/ssl_utils.cc +26 -31
  135. data/src/core/lib/security/security_connector/ssl_utils.h +11 -8
  136. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +16 -20
  137. data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +4 -3
  138. data/src/core/lib/security/transport/client_auth_filter.cc +1 -2
  139. data/src/core/lib/security/util/json_util.cc +19 -5
  140. data/src/core/lib/security/util/json_util.h +3 -1
  141. data/src/core/lib/slice/slice.cc +69 -50
  142. data/src/core/lib/slice/slice_buffer.cc +6 -5
  143. data/src/core/lib/slice/slice_hash_table.h +3 -7
  144. data/src/core/lib/slice/slice_intern.cc +130 -39
  145. data/src/core/lib/slice/slice_internal.h +8 -0
  146. data/src/core/lib/slice/slice_utils.h +120 -0
  147. data/src/core/lib/slice/slice_weak_hash_table.h +2 -7
  148. data/src/core/lib/surface/call.cc +8 -3
  149. data/src/core/lib/surface/channel.cc +31 -8
  150. data/src/core/lib/surface/completion_queue.cc +17 -7
  151. data/src/core/lib/surface/init_secure.cc +4 -1
  152. data/src/core/lib/surface/lame_client.cc +2 -2
  153. data/src/core/lib/surface/server.cc +34 -35
  154. data/src/core/lib/surface/server.h +8 -17
  155. data/src/core/lib/surface/version.cc +1 -1
  156. data/src/core/lib/transport/byte_stream.cc +3 -5
  157. data/src/core/lib/transport/byte_stream.h +1 -2
  158. data/src/core/lib/transport/error_utils.cc +10 -1
  159. data/src/core/lib/transport/metadata.cc +202 -35
  160. data/src/core/lib/transport/metadata.h +81 -6
  161. data/src/core/lib/transport/static_metadata.cc +1257 -465
  162. data/src/core/lib/transport/static_metadata.h +190 -347
  163. data/src/core/lib/transport/timeout_encoding.cc +7 -0
  164. data/src/core/lib/transport/timeout_encoding.h +3 -2
  165. data/src/core/plugin_registry/grpc_plugin_registry.cc +4 -0
  166. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +0 -1
  167. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -7
  168. data/src/core/tsi/ssl_transport_security.cc +35 -43
  169. data/src/core/tsi/ssl_transport_security.h +2 -1
  170. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  171. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  172. data/src/ruby/lib/grpc/generic/rpc_server.rb +1 -1
  173. data/src/ruby/lib/grpc/grpc.rb +1 -1
  174. data/src/ruby/lib/grpc/version.rb +1 -1
  175. metadata +39 -33
  176. data/src/core/lib/gpr/host_port.cc +0 -98
@@ -23,7 +23,6 @@
23
23
 
24
24
  #include "src/core/ext/filters/client_channel/client_channel_channelz.h"
25
25
  #include "src/core/ext/filters/client_channel/connector.h"
26
- #include "src/core/ext/filters/client_channel/subchannel_interface.h"
27
26
  #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
28
27
  #include "src/core/lib/backoff/backoff.h"
29
28
  #include "src/core/lib/channel/channel_stack.h"
@@ -70,38 +69,23 @@ namespace grpc_core {
70
69
 
71
70
  class SubchannelCall;
72
71
 
73
- class ConnectedSubchannel : public ConnectedSubchannelInterface {
72
+ class ConnectedSubchannel : public RefCounted<ConnectedSubchannel> {
74
73
  public:
75
- struct CallArgs {
76
- grpc_polling_entity* pollent;
77
- grpc_slice path;
78
- gpr_timespec start_time;
79
- grpc_millis deadline;
80
- Arena* arena;
81
- grpc_call_context_element* context;
82
- CallCombiner* call_combiner;
83
- size_t parent_data_size;
84
- };
85
-
86
74
  ConnectedSubchannel(
87
75
  grpc_channel_stack* channel_stack, const grpc_channel_args* args,
88
- RefCountedPtr<channelz::SubchannelNode> channelz_subchannel,
89
- intptr_t socket_uuid);
76
+ RefCountedPtr<channelz::SubchannelNode> channelz_subchannel);
90
77
  ~ConnectedSubchannel();
91
78
 
92
79
  void NotifyOnStateChange(grpc_pollset_set* interested_parties,
93
80
  grpc_connectivity_state* state,
94
81
  grpc_closure* closure);
95
82
  void Ping(grpc_closure* on_initiate, grpc_closure* on_ack);
96
- RefCountedPtr<SubchannelCall> CreateCall(const CallArgs& args,
97
- grpc_error** error);
98
83
 
99
84
  grpc_channel_stack* channel_stack() const { return channel_stack_; }
100
- const grpc_channel_args* args() const override { return args_; }
85
+ const grpc_channel_args* args() const { return args_; }
101
86
  channelz::SubchannelNode* channelz_subchannel() const {
102
87
  return channelz_subchannel_.get();
103
88
  }
104
- intptr_t socket_uuid() const { return socket_uuid_; }
105
89
 
106
90
  size_t GetInitialCallSizeEstimate(size_t parent_data_size) const;
107
91
 
@@ -111,17 +95,23 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface {
111
95
  // ref counted pointer to the channelz node in this connected subchannel's
112
96
  // owning subchannel.
113
97
  RefCountedPtr<channelz::SubchannelNode> channelz_subchannel_;
114
- // uuid of this subchannel's socket. 0 if this subchannel is not connected.
115
- const intptr_t socket_uuid_;
116
98
  };
117
99
 
118
100
  // Implements the interface of RefCounted<>.
119
101
  class SubchannelCall {
120
102
  public:
121
- SubchannelCall(RefCountedPtr<ConnectedSubchannel> connected_subchannel,
122
- const ConnectedSubchannel::CallArgs& args)
123
- : connected_subchannel_(std::move(connected_subchannel)),
124
- deadline_(args.deadline) {}
103
+ struct Args {
104
+ RefCountedPtr<ConnectedSubchannel> connected_subchannel;
105
+ grpc_polling_entity* pollent;
106
+ grpc_slice path;
107
+ gpr_timespec start_time;
108
+ grpc_millis deadline;
109
+ Arena* arena;
110
+ grpc_call_context_element* context;
111
+ CallCombiner* call_combiner;
112
+ size_t parent_data_size;
113
+ };
114
+ static RefCountedPtr<SubchannelCall> Create(Args args, grpc_error** error);
125
115
 
126
116
  // Continues processing a transport stream op batch.
127
117
  void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch);
@@ -154,6 +144,8 @@ class SubchannelCall {
154
144
  template <typename T>
155
145
  friend class RefCountedPtr;
156
146
 
147
+ SubchannelCall(Args args, grpc_error** error);
148
+
157
149
  // If channelz is enabled, intercepts recv_trailing so that we may check the
158
150
  // status and associate it to a subchannel.
159
151
  void MaybeInterceptRecvTrailingMetadata(
@@ -176,10 +168,35 @@ class SubchannelCall {
176
168
 
177
169
  // A subchannel that knows how to connect to exactly one target address. It
178
170
  // provides a target for load balancing.
171
+ //
172
+ // Note that this is the "real" subchannel implementation, whose API is
173
+ // different from the SubchannelInterface that is exposed to LB policy
174
+ // implementations. The client channel provides an adaptor class
175
+ // (SubchannelWrapper) that "converts" between the two.
179
176
  class Subchannel {
180
177
  public:
181
- typedef SubchannelInterface::ConnectivityStateWatcher
182
- ConnectivityStateWatcher;
178
+ class ConnectivityStateWatcherInterface
179
+ : public InternallyRefCounted<ConnectivityStateWatcherInterface> {
180
+ public:
181
+ virtual ~ConnectivityStateWatcherInterface() = default;
182
+
183
+ // Will be invoked whenever the subchannel's connectivity state
184
+ // changes. There will be only one invocation of this method on a
185
+ // given watcher instance at any given time.
186
+ //
187
+ // When the state changes to READY, connected_subchannel will
188
+ // contain a ref to the connected subchannel. When it changes from
189
+ // READY to some other state, the implementation must release its
190
+ // ref to the connected subchannel.
191
+ virtual void OnConnectivityStateChange(
192
+ grpc_connectivity_state new_state,
193
+ RefCountedPtr<ConnectedSubchannel> connected_subchannel) // NOLINT
194
+ GRPC_ABSTRACT;
195
+
196
+ virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT;
197
+
198
+ GRPC_ABSTRACT_BASE_CLASS
199
+ };
183
200
 
184
201
  // The ctor and dtor are not intended to use directly.
185
202
  Subchannel(SubchannelKey* key, grpc_connector* connector,
@@ -200,12 +217,12 @@ class Subchannel {
200
217
  // returns null.
201
218
  Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
202
219
 
203
- intptr_t GetChildSocketUuid();
204
-
205
220
  // Gets the string representing the subchannel address.
206
221
  // Caller doesn't take ownership.
207
222
  const char* GetTargetAddress();
208
223
 
224
+ const grpc_channel_args* channel_args() const { return args_; }
225
+
209
226
  channelz::SubchannelNode* channelz_node();
210
227
 
211
228
  // Returns the current connectivity state of the subchannel.
@@ -225,14 +242,15 @@ class Subchannel {
225
242
  // changes.
226
243
  // The watcher will be destroyed either when the subchannel is
227
244
  // destroyed or when CancelConnectivityStateWatch() is called.
228
- void WatchConnectivityState(grpc_connectivity_state initial_state,
229
- UniquePtr<char> health_check_service_name,
230
- UniquePtr<ConnectivityStateWatcher> watcher);
245
+ void WatchConnectivityState(
246
+ grpc_connectivity_state initial_state,
247
+ UniquePtr<char> health_check_service_name,
248
+ OrphanablePtr<ConnectivityStateWatcherInterface> watcher);
231
249
 
232
250
  // Cancels a connectivity state watch.
233
251
  // If the watcher has already been destroyed, this is a no-op.
234
252
  void CancelConnectivityStateWatch(const char* health_check_service_name,
235
- ConnectivityStateWatcher* watcher);
253
+ ConnectivityStateWatcherInterface* watcher);
236
254
 
237
255
  // Attempt to connect to the backend. Has no effect if already connected.
238
256
  void AttemptToConnect();
@@ -257,14 +275,15 @@ class Subchannel {
257
275
  grpc_resolved_address* addr);
258
276
 
259
277
  private:
260
- // A linked list of ConnectivityStateWatchers that are monitoring the
261
- // subchannel's state.
278
+ // A linked list of ConnectivityStateWatcherInterfaces that are monitoring
279
+ // the subchannel's state.
262
280
  class ConnectivityStateWatcherList {
263
281
  public:
264
282
  ~ConnectivityStateWatcherList() { Clear(); }
265
283
 
266
- void AddWatcherLocked(UniquePtr<ConnectivityStateWatcher> watcher);
267
- void RemoveWatcherLocked(ConnectivityStateWatcher* watcher);
284
+ void AddWatcherLocked(
285
+ OrphanablePtr<ConnectivityStateWatcherInterface> watcher);
286
+ void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher);
268
287
 
269
288
  // Notifies all watchers in the list about a change to state.
270
289
  void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state);
@@ -276,12 +295,13 @@ class Subchannel {
276
295
  private:
277
296
  // TODO(roth): This could be a set instead of a map if we had a set
278
297
  // implementation.
279
- Map<ConnectivityStateWatcher*, UniquePtr<ConnectivityStateWatcher>>
298
+ Map<ConnectivityStateWatcherInterface*,
299
+ OrphanablePtr<ConnectivityStateWatcherInterface>>
280
300
  watchers_;
281
301
  };
282
302
 
283
- // A map that tracks ConnectivityStateWatchers using a particular health
284
- // check service name.
303
+ // A map that tracks ConnectivityStateWatcherInterfaces using a particular
304
+ // health check service name.
285
305
  //
286
306
  // There is one entry in the map for each health check service name.
287
307
  // Entries exist only as long as there are watchers using the
@@ -291,12 +311,12 @@ class Subchannel {
291
311
  // state READY.
292
312
  class HealthWatcherMap {
293
313
  public:
294
- void AddWatcherLocked(Subchannel* subchannel,
295
- grpc_connectivity_state initial_state,
296
- UniquePtr<char> health_check_service_name,
297
- UniquePtr<ConnectivityStateWatcher> watcher);
314
+ void AddWatcherLocked(
315
+ Subchannel* subchannel, grpc_connectivity_state initial_state,
316
+ UniquePtr<char> health_check_service_name,
317
+ OrphanablePtr<ConnectivityStateWatcherInterface> watcher);
298
318
  void RemoveWatcherLocked(const char* health_check_service_name,
299
- ConnectivityStateWatcher* watcher);
319
+ ConnectivityStateWatcherInterface* watcher);
300
320
 
301
321
  // Notifies the watcher when the subchannel's state changes.
302
322
  void NotifyLocked(grpc_connectivity_state state);
@@ -21,42 +21,22 @@
21
21
 
22
22
  #include <grpc/support/port_platform.h>
23
23
 
24
- #include "src/core/lib/debug/trace.h"
25
24
  #include "src/core/lib/gprpp/ref_counted.h"
26
25
  #include "src/core/lib/gprpp/ref_counted_ptr.h"
27
26
 
28
27
  namespace grpc_core {
29
28
 
30
- // TODO(roth): In a subsequent PR, remove this from this API.
31
- class ConnectedSubchannelInterface
32
- : public RefCounted<ConnectedSubchannelInterface> {
33
- public:
34
- virtual const grpc_channel_args* args() const GRPC_ABSTRACT;
35
-
36
- protected:
37
- template <typename TraceFlagT = TraceFlag>
38
- explicit ConnectedSubchannelInterface(TraceFlagT* trace_flag = nullptr)
39
- : RefCounted<ConnectedSubchannelInterface>(trace_flag) {}
40
- };
41
-
29
+ // The interface for subchannels that is exposed to LB policy implementations.
42
30
  class SubchannelInterface : public RefCounted<SubchannelInterface> {
43
31
  public:
44
- class ConnectivityStateWatcher {
32
+ class ConnectivityStateWatcherInterface {
45
33
  public:
46
- virtual ~ConnectivityStateWatcher() = default;
34
+ virtual ~ConnectivityStateWatcherInterface() = default;
47
35
 
48
36
  // Will be invoked whenever the subchannel's connectivity state
49
37
  // changes. There will be only one invocation of this method on a
50
38
  // given watcher instance at any given time.
51
- //
52
- // When the state changes to READY, connected_subchannel will
53
- // contain a ref to the connected subchannel. When it changes from
54
- // READY to some other state, the implementation must release its
55
- // ref to the connected subchannel.
56
- virtual void OnConnectivityStateChange(
57
- grpc_connectivity_state new_state,
58
- RefCountedPtr<ConnectedSubchannelInterface>
59
- connected_subchannel) // NOLINT
39
+ virtual void OnConnectivityStateChange(grpc_connectivity_state new_state)
60
40
  GRPC_ABSTRACT;
61
41
 
62
42
  // TODO(roth): Remove this as soon as we move to EventManager-based
@@ -66,12 +46,14 @@ class SubchannelInterface : public RefCounted<SubchannelInterface> {
66
46
  GRPC_ABSTRACT_BASE_CLASS
67
47
  };
68
48
 
49
+ template <typename TraceFlagT = TraceFlag>
50
+ explicit SubchannelInterface(TraceFlagT* trace_flag = nullptr)
51
+ : RefCounted<SubchannelInterface>(trace_flag) {}
52
+
69
53
  virtual ~SubchannelInterface() = default;
70
54
 
71
55
  // Returns the current connectivity state of the subchannel.
72
- virtual grpc_connectivity_state CheckConnectivityState(
73
- RefCountedPtr<ConnectedSubchannelInterface>* connected_subchannel)
74
- GRPC_ABSTRACT;
56
+ virtual grpc_connectivity_state CheckConnectivityState() GRPC_ABSTRACT;
75
57
 
76
58
  // Starts watching the subchannel's connectivity state.
77
59
  // The first callback to the watcher will be delivered when the
@@ -86,12 +68,12 @@ class SubchannelInterface : public RefCounted<SubchannelInterface> {
86
68
  // the previous watcher using CancelConnectivityStateWatch().
87
69
  virtual void WatchConnectivityState(
88
70
  grpc_connectivity_state initial_state,
89
- UniquePtr<ConnectivityStateWatcher> watcher) GRPC_ABSTRACT;
71
+ UniquePtr<ConnectivityStateWatcherInterface> watcher) GRPC_ABSTRACT;
90
72
 
91
73
  // Cancels a connectivity state watch.
92
74
  // If the watcher has already been destroyed, this is a no-op.
93
- virtual void CancelConnectivityStateWatch(ConnectivityStateWatcher* watcher)
94
- GRPC_ABSTRACT;
75
+ virtual void CancelConnectivityStateWatch(
76
+ ConnectivityStateWatcherInterface* watcher) GRPC_ABSTRACT;
95
77
 
96
78
  // Attempt to connect to the backend. Has no effect if already connected.
97
79
  // If the subchannel is currently in backoff delay due to a previously
@@ -105,6 +87,9 @@ class SubchannelInterface : public RefCounted<SubchannelInterface> {
105
87
  // attempt will be started as soon as AttemptToConnect() is called.
106
88
  virtual void ResetBackoff() GRPC_ABSTRACT;
107
89
 
90
+ // TODO(roth): Need a better non-grpc-specific abstraction here.
91
+ virtual const grpc_channel_args* channel_args() GRPC_ABSTRACT;
92
+
108
93
  GRPC_ABSTRACT_BASE_CLASS
109
94
  };
110
95
 
@@ -0,0 +1,262 @@
1
+ /*
2
+ *
3
+ * Copyright 2019 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
+ #include <grpc/support/port_platform.h>
20
+
21
+ #include <limits.h>
22
+
23
+ #include "src/core/lib/channel/channel_args.h"
24
+ #include "src/core/lib/channel/channel_stack_builder.h"
25
+ #include "src/core/lib/gprpp/atomic.h"
26
+ #include "src/core/lib/iomgr/timer.h"
27
+ #include "src/core/lib/surface/channel_init.h"
28
+ #include "src/core/lib/transport/http2_errors.h"
29
+
30
+ // The idle filter is disabled in client channel by default.
31
+ // To enable the idle filte, set GRPC_ARG_CLIENT_IDLE_TIMEOUT_MS to [0, INT_MAX)
32
+ // in channel args.
33
+ // TODO(qianchengz): Find a reasonable default value. Maybe check what deault
34
+ // value Java uses.
35
+ #define DEFAULT_IDLE_TIMEOUT_MS INT_MAX
36
+
37
+ namespace grpc_core {
38
+
39
+ TraceFlag grpc_trace_client_idle_filter(false, "client_idle_filter");
40
+
41
+ #define GRPC_IDLE_FILTER_LOG(format, ...) \
42
+ do { \
43
+ if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_client_idle_filter)) { \
44
+ gpr_log(GPR_INFO, "(client idle filter) " format, ##__VA_ARGS__); \
45
+ } \
46
+ } while (0)
47
+
48
+ namespace {
49
+
50
+ grpc_millis GetClientIdleTimeout(const grpc_channel_args* args) {
51
+ return grpc_channel_arg_get_integer(
52
+ grpc_channel_args_find(args, GRPC_ARG_CLIENT_IDLE_TIMEOUT_MS),
53
+ {DEFAULT_IDLE_TIMEOUT_MS, 0, INT_MAX});
54
+ }
55
+
56
+ class ChannelData {
57
+ public:
58
+ static grpc_error* Init(grpc_channel_element* elem,
59
+ grpc_channel_element_args* args);
60
+ static void Destroy(grpc_channel_element* elem);
61
+
62
+ static void StartTransportOp(grpc_channel_element* elem,
63
+ grpc_transport_op* op);
64
+
65
+ void IncreaseCallCount();
66
+
67
+ void DecreaseCallCount();
68
+
69
+ private:
70
+ ChannelData(grpc_channel_element* elem, grpc_channel_element_args* args,
71
+ grpc_error** error);
72
+ ~ChannelData() = default;
73
+
74
+ static void IdleTimerCallback(void* arg, grpc_error* error);
75
+ static void IdleTransportOpCompleteCallback(void* arg, grpc_error* error);
76
+
77
+ void StartIdleTimer();
78
+
79
+ void EnterIdle();
80
+
81
+ grpc_channel_element* elem_;
82
+ // The channel stack to which we take refs for pending callbacks.
83
+ grpc_channel_stack* channel_stack_;
84
+ // Timeout after the last RPC finishes on the client channel at which the
85
+ // channel goes back into IDLE state.
86
+ const grpc_millis client_idle_timeout_;
87
+
88
+ // Member data used to track the state of channel.
89
+ Mutex call_count_mu_;
90
+ size_t call_count_;
91
+
92
+ // Idle timer and its callback closure.
93
+ grpc_timer idle_timer_;
94
+ grpc_closure idle_timer_callback_;
95
+
96
+ // The transport op telling the client channel to enter IDLE.
97
+ grpc_transport_op idle_transport_op_;
98
+ grpc_closure idle_transport_op_complete_callback_;
99
+ };
100
+
101
+ grpc_error* ChannelData::Init(grpc_channel_element* elem,
102
+ grpc_channel_element_args* args) {
103
+ grpc_error* error = GRPC_ERROR_NONE;
104
+ new (elem->channel_data) ChannelData(elem, args, &error);
105
+ return error;
106
+ }
107
+
108
+ void ChannelData::Destroy(grpc_channel_element* elem) {
109
+ ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
110
+ chand->~ChannelData();
111
+ }
112
+
113
+ void ChannelData::StartTransportOp(grpc_channel_element* elem,
114
+ grpc_transport_op* op) {
115
+ ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
116
+ // Catch the disconnect_with_error transport op.
117
+ if (op->disconnect_with_error != nullptr) {
118
+ // Disconnect. Cancel the timer if we set it before.
119
+ // IncreaseCallCount() introduces a dummy call. It will cancel the timer and
120
+ // prevent the timer from being reset by other threads.
121
+ chand->IncreaseCallCount();
122
+ }
123
+ // Pass the op to the next filter.
124
+ grpc_channel_next_op(elem, op);
125
+ }
126
+
127
+ void ChannelData::IncreaseCallCount() {
128
+ MutexLock lock(&call_count_mu_);
129
+ if (call_count_++ == 0) {
130
+ grpc_timer_cancel(&idle_timer_);
131
+ }
132
+ GRPC_IDLE_FILTER_LOG("call counter has increased to %" PRIuPTR, call_count_);
133
+ }
134
+
135
+ void ChannelData::DecreaseCallCount() {
136
+ MutexLock lock(&call_count_mu_);
137
+ if (call_count_-- == 1) {
138
+ StartIdleTimer();
139
+ }
140
+ GRPC_IDLE_FILTER_LOG("call counter has decreased to %" PRIuPTR, call_count_);
141
+ }
142
+
143
+ ChannelData::ChannelData(grpc_channel_element* elem,
144
+ grpc_channel_element_args* args, grpc_error** error)
145
+ : elem_(elem),
146
+ channel_stack_(args->channel_stack),
147
+ client_idle_timeout_(GetClientIdleTimeout(args->channel_args)),
148
+ call_count_(0) {
149
+ // If the idle filter is explicitly disabled in channel args, this ctor should
150
+ // not get called.
151
+ GPR_ASSERT(client_idle_timeout_ != GRPC_MILLIS_INF_FUTURE);
152
+ GRPC_IDLE_FILTER_LOG("created with max_leisure_time = %" PRId64 " ms",
153
+ client_idle_timeout_);
154
+ // Initialize the idle timer without setting it.
155
+ grpc_timer_init_unset(&idle_timer_);
156
+ // Initialize the idle timer callback closure.
157
+ GRPC_CLOSURE_INIT(&idle_timer_callback_, IdleTimerCallback, this,
158
+ grpc_schedule_on_exec_ctx);
159
+ // Initialize the idle transport op complete callback.
160
+ GRPC_CLOSURE_INIT(&idle_transport_op_complete_callback_,
161
+ IdleTransportOpCompleteCallback, this,
162
+ grpc_schedule_on_exec_ctx);
163
+ }
164
+
165
+ void ChannelData::IdleTimerCallback(void* arg, grpc_error* error) {
166
+ GRPC_IDLE_FILTER_LOG("timer alarms");
167
+ ChannelData* chand = static_cast<ChannelData*>(arg);
168
+ {
169
+ MutexLock lock(&chand->call_count_mu_);
170
+ if (error == GRPC_ERROR_NONE && chand->call_count_ == 0) {
171
+ chand->EnterIdle();
172
+ }
173
+ }
174
+ GRPC_IDLE_FILTER_LOG("timer finishes");
175
+ GRPC_CHANNEL_STACK_UNREF(chand->channel_stack_, "max idle timer callback");
176
+ }
177
+
178
+ void ChannelData::IdleTransportOpCompleteCallback(void* arg,
179
+ grpc_error* error) {
180
+ ChannelData* chand = static_cast<ChannelData*>(arg);
181
+ GRPC_CHANNEL_STACK_UNREF(chand->channel_stack_, "idle transport op");
182
+ }
183
+
184
+ void ChannelData::StartIdleTimer() {
185
+ GRPC_IDLE_FILTER_LOG("timer has started");
186
+ // Hold a ref to the channel stack for the timer callback.
187
+ GRPC_CHANNEL_STACK_REF(channel_stack_, "max idle timer callback");
188
+ grpc_timer_init(&idle_timer_, ExecCtx::Get()->Now() + client_idle_timeout_,
189
+ &idle_timer_callback_);
190
+ }
191
+
192
+ void ChannelData::EnterIdle() {
193
+ GRPC_IDLE_FILTER_LOG("the channel will enter IDLE");
194
+ // Hold a ref to the channel stack for the transport op.
195
+ GRPC_CHANNEL_STACK_REF(channel_stack_, "idle transport op");
196
+ idle_transport_op_.disconnect_with_error = grpc_error_set_int(
197
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("enter idle"),
198
+ GRPC_ERROR_INT_CHANNEL_CONNECTIVITY_STATE, GRPC_CHANNEL_IDLE);
199
+ idle_transport_op_.on_consumed = &idle_transport_op_complete_callback_;
200
+ // Pass the transport op down to the channel stack.
201
+ grpc_channel_next_op(elem_, &idle_transport_op_);
202
+ }
203
+
204
+ class CallData {
205
+ public:
206
+ static grpc_error* Init(grpc_call_element* elem,
207
+ const grpc_call_element_args* args);
208
+ static void Destroy(grpc_call_element* elem,
209
+ const grpc_call_final_info* final_info,
210
+ grpc_closure* then_schedule_closure);
211
+ };
212
+
213
+ grpc_error* CallData::Init(grpc_call_element* elem,
214
+ const grpc_call_element_args* args) {
215
+ ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
216
+ chand->IncreaseCallCount();
217
+ return GRPC_ERROR_NONE;
218
+ }
219
+
220
+ void CallData::Destroy(grpc_call_element* elem,
221
+ const grpc_call_final_info* final_info,
222
+ grpc_closure* ignored) {
223
+ ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
224
+ chand->DecreaseCallCount();
225
+ }
226
+
227
+ const grpc_channel_filter grpc_client_idle_filter = {
228
+ grpc_call_next_op,
229
+ ChannelData::StartTransportOp,
230
+ sizeof(CallData),
231
+ CallData::Init,
232
+ grpc_call_stack_ignore_set_pollset_or_pollset_set,
233
+ CallData::Destroy,
234
+ sizeof(ChannelData),
235
+ ChannelData::Init,
236
+ ChannelData::Destroy,
237
+ grpc_channel_next_get_info,
238
+ "client_idle"};
239
+
240
+ static bool MaybeAddClientIdleFilter(grpc_channel_stack_builder* builder,
241
+ void* arg) {
242
+ const grpc_channel_args* channel_args =
243
+ grpc_channel_stack_builder_get_channel_arguments(builder);
244
+ if (!grpc_channel_args_want_minimal_stack(channel_args) &&
245
+ GetClientIdleTimeout(channel_args) != INT_MAX) {
246
+ return grpc_channel_stack_builder_prepend_filter(
247
+ builder, &grpc_client_idle_filter, nullptr, nullptr);
248
+ } else {
249
+ return true;
250
+ }
251
+ }
252
+
253
+ } // namespace
254
+ } // namespace grpc_core
255
+
256
+ void grpc_client_idle_filter_init(void) {
257
+ grpc_channel_init_register_stage(
258
+ GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
259
+ grpc_core::MaybeAddClientIdleFilter, nullptr);
260
+ }
261
+
262
+ void grpc_client_idle_filter_shutdown(void) {}