grpc 1.11.1 → 1.12.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.
- checksums.yaml +4 -4
- data/Makefile +225 -87
- data/etc/roots.pem +0 -33
- data/include/grpc/grpc_security.h +70 -0
- data/include/grpc/impl/codegen/port_platform.h +11 -0
- data/include/grpc/support/log.h +9 -1
- data/src/core/ext/filters/client_channel/client_channel.cc +305 -210
- data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +1 -1
- data/src/core/ext/filters/client_channel/lb_policy.cc +2 -2
- data/src/core/ext/filters/client_channel/lb_policy.h +4 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +12 -9
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +168 -197
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +368 -373
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +498 -98
- data/src/core/ext/filters/client_channel/method_params.h +4 -0
- data/src/core/ext/filters/client_channel/resolver.h +4 -0
- data/src/core/ext/filters/client_channel/retry_throttle.h +4 -0
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +40 -15
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/hpack_table.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/writing.cc +5 -5
- data/src/core/ext/transport/inproc/inproc_transport.cc +41 -43
- data/src/core/lib/channel/channel_args.cc +28 -0
- data/src/core/lib/channel/channel_args.h +4 -0
- data/src/core/lib/channel/handshaker.cc +47 -0
- data/src/core/lib/channel/handshaker.h +4 -0
- data/src/core/lib/debug/trace.cc +2 -1
- data/src/core/lib/debug/trace.h +10 -1
- data/src/core/lib/gpr/log.cc +8 -2
- data/src/core/lib/gpr/log_android.cc +4 -0
- data/src/core/lib/gpr/log_linux.cc +4 -0
- data/src/core/lib/gpr/log_posix.cc +4 -0
- data/src/core/lib/gpr/log_windows.cc +5 -0
- data/src/core/lib/gprpp/inlined_vector.h +30 -34
- data/src/core/lib/gprpp/orphanable.h +4 -4
- data/src/core/lib/gprpp/ref_counted.h +4 -4
- data/src/core/lib/iomgr/call_combiner.cc +13 -13
- data/src/core/lib/iomgr/closure.h +3 -3
- data/src/core/lib/iomgr/combiner.cc +11 -11
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +24 -24
- data/src/core/lib/iomgr/ev_epollex_linux.cc +48 -29
- data/src/core/lib/iomgr/ev_epollsig_linux.cc +2 -2
- data/src/core/lib/iomgr/ev_poll_posix.cc +9 -3
- data/src/core/lib/iomgr/ev_posix.cc +3 -3
- data/src/core/lib/iomgr/executor.cc +6 -6
- data/src/core/lib/iomgr/resource_quota.cc +10 -11
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +24 -0
- data/src/core/lib/iomgr/socket_utils_linux.cc +0 -1
- data/src/core/lib/iomgr/socket_utils_posix.cc +2 -3
- data/src/core/lib/iomgr/socket_utils_posix.h +3 -0
- data/src/core/lib/iomgr/tcp_client_custom.cc +2 -2
- data/src/core/lib/iomgr/tcp_client_posix.cc +4 -4
- data/src/core/lib/iomgr/tcp_custom.cc +10 -10
- data/src/core/lib/iomgr/tcp_posix.cc +25 -25
- data/src/core/lib/iomgr/tcp_server_custom.cc +5 -5
- data/src/core/lib/iomgr/tcp_server_posix.cc +4 -25
- data/src/core/lib/iomgr/tcp_server_windows.cc +1 -0
- data/src/core/lib/iomgr/tcp_uv.cc +3 -0
- data/src/core/lib/iomgr/tcp_windows.cc +16 -0
- data/src/core/lib/iomgr/timer_generic.cc +27 -17
- data/src/core/lib/iomgr/timer_manager.cc +11 -12
- data/src/core/lib/iomgr/timer_uv.cc +3 -0
- data/src/core/lib/iomgr/udp_server.cc +104 -49
- data/src/core/lib/iomgr/udp_server.h +8 -4
- data/src/core/lib/profiling/basic_timers.cc +1 -0
- data/src/core/lib/security/credentials/alts/alts_credentials.h +0 -20
- data/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc +7 -7
- data/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h +1 -38
- data/src/core/lib/security/security_connector/security_connector.cc +19 -16
- data/src/core/lib/security/security_connector/security_connector.h +4 -3
- data/src/core/lib/security/transport/secure_endpoint.cc +2 -2
- data/src/core/lib/security/transport/security_handshaker.cc +6 -2
- data/src/core/lib/slice/slice.cc +6 -2
- data/src/core/lib/slice/slice_buffer.cc +12 -4
- data/src/core/lib/slice/slice_hash_table.h +4 -0
- data/src/core/lib/slice/slice_weak_hash_table.h +4 -0
- data/src/core/lib/surface/call.cc +6 -6
- data/src/core/lib/surface/server.cc +16 -0
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/bdp_estimator.cc +3 -3
- data/src/core/lib/transport/bdp_estimator.h +2 -2
- data/src/core/lib/transport/connectivity_state.cc +6 -7
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +4 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +14 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +21 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/generate_proto_ruby.sh +7 -1
- data/src/ruby/spec/pb/package_with_underscore/checker_spec.rb +2 -5
- data/third_party/address_sorting/address_sorting.c +10 -9
- metadata +27 -28
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc +0 -253
@@ -326,7 +326,7 @@ static void http_connect_handshaker_do_handshake(
|
|
326
326
|
|
327
327
|
static const grpc_handshaker_vtable http_connect_handshaker_vtable = {
|
328
328
|
http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
|
329
|
-
http_connect_handshaker_do_handshake};
|
329
|
+
http_connect_handshaker_do_handshake, "http_connect"};
|
330
330
|
|
331
331
|
static grpc_handshaker* grpc_http_connect_handshaker_create() {
|
332
332
|
http_connect_handshaker* handshaker =
|
@@ -44,13 +44,13 @@ void LoadBalancingPolicy::TryReresolutionLocked(
|
|
44
44
|
GRPC_CLOSURE_SCHED(request_reresolution_, error);
|
45
45
|
request_reresolution_ = nullptr;
|
46
46
|
if (grpc_lb_trace->enabled()) {
|
47
|
-
gpr_log(
|
47
|
+
gpr_log(GPR_INFO,
|
48
48
|
"%s %p: scheduling re-resolution closure with error=%s.",
|
49
49
|
grpc_lb_trace->name(), this, grpc_error_string(error));
|
50
50
|
}
|
51
51
|
} else {
|
52
52
|
if (grpc_lb_trace->enabled()) {
|
53
|
-
gpr_log(
|
53
|
+
gpr_log(GPR_INFO, "%s %p: no available re-resolution closure.",
|
54
54
|
grpc_lb_trace->name(), this);
|
55
55
|
}
|
56
56
|
}
|
@@ -162,6 +162,10 @@ class LoadBalancingPolicy
|
|
162
162
|
GRPC_ABSTRACT_BASE_CLASS
|
163
163
|
|
164
164
|
protected:
|
165
|
+
// So Delete() can access our protected dtor.
|
166
|
+
template <typename T>
|
167
|
+
friend void Delete(T*);
|
168
|
+
|
165
169
|
explicit LoadBalancingPolicy(const Args& args);
|
166
170
|
virtual ~LoadBalancingPolicy();
|
167
171
|
|
@@ -189,6 +189,10 @@ class GrpcLb : public LoadBalancingPolicy {
|
|
189
189
|
bool seen_initial_response() const { return seen_initial_response_; }
|
190
190
|
|
191
191
|
private:
|
192
|
+
// So Delete() can access our private dtor.
|
193
|
+
template <typename T>
|
194
|
+
friend void grpc_core::Delete(T*);
|
195
|
+
|
192
196
|
~BalancerCallState();
|
193
197
|
|
194
198
|
GrpcLb* grpclb_policy() const {
|
@@ -1243,7 +1247,7 @@ bool GrpcLb::PickLocked(PickState* pick) {
|
|
1243
1247
|
}
|
1244
1248
|
} else { // rr_policy_ == NULL
|
1245
1249
|
if (grpc_lb_glb_trace.enabled()) {
|
1246
|
-
gpr_log(
|
1250
|
+
gpr_log(GPR_INFO,
|
1247
1251
|
"[grpclb %p] No RR policy. Adding to grpclb's pending picks",
|
1248
1252
|
this);
|
1249
1253
|
}
|
@@ -1409,14 +1413,13 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
|
|
1409
1413
|
void GrpcLb::StartBalancerCallRetryTimerLocked() {
|
1410
1414
|
grpc_millis next_try = lb_call_backoff_.NextAttemptTime();
|
1411
1415
|
if (grpc_lb_glb_trace.enabled()) {
|
1412
|
-
gpr_log(
|
1416
|
+
gpr_log(GPR_INFO, "[grpclb %p] Connection to LB server lost...", this);
|
1413
1417
|
grpc_millis timeout = next_try - ExecCtx::Get()->Now();
|
1414
1418
|
if (timeout > 0) {
|
1415
|
-
gpr_log(
|
1416
|
-
|
1417
|
-
timeout);
|
1419
|
+
gpr_log(GPR_INFO, "[grpclb %p] ... retry_timer_active in %" PRIuPTR "ms.",
|
1420
|
+
this, timeout);
|
1418
1421
|
} else {
|
1419
|
-
gpr_log(
|
1422
|
+
gpr_log(GPR_INFO, "[grpclb %p] ... retry_timer_active immediately.",
|
1420
1423
|
this);
|
1421
1424
|
}
|
1422
1425
|
}
|
@@ -1724,7 +1727,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() {
|
|
1724
1727
|
GPR_ASSERT(args != nullptr);
|
1725
1728
|
if (rr_policy_ != nullptr) {
|
1726
1729
|
if (grpc_lb_glb_trace.enabled()) {
|
1727
|
-
gpr_log(
|
1730
|
+
gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this,
|
1728
1731
|
rr_policy_.get());
|
1729
1732
|
}
|
1730
1733
|
rr_policy_->UpdateLocked(*args);
|
@@ -1735,7 +1738,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() {
|
|
1735
1738
|
lb_policy_args.args = args;
|
1736
1739
|
CreateRoundRobinPolicyLocked(lb_policy_args);
|
1737
1740
|
if (grpc_lb_glb_trace.enabled()) {
|
1738
|
-
gpr_log(
|
1741
|
+
gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this,
|
1739
1742
|
rr_policy_.get());
|
1740
1743
|
}
|
1741
1744
|
}
|
@@ -1751,7 +1754,7 @@ void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg,
|
|
1751
1754
|
}
|
1752
1755
|
if (grpc_lb_glb_trace.enabled()) {
|
1753
1756
|
gpr_log(
|
1754
|
-
|
1757
|
+
GPR_INFO,
|
1755
1758
|
"[grpclb %p] Re-resolution requested from the internal RR policy (%p).",
|
1756
1759
|
grpclb_policy, grpclb_policy->rr_policy_.get());
|
1757
1760
|
}
|
@@ -62,31 +62,65 @@ class PickFirst : public LoadBalancingPolicy {
|
|
62
62
|
private:
|
63
63
|
~PickFirst();
|
64
64
|
|
65
|
+
class PickFirstSubchannelList;
|
66
|
+
|
67
|
+
class PickFirstSubchannelData
|
68
|
+
: public SubchannelData<PickFirstSubchannelList,
|
69
|
+
PickFirstSubchannelData> {
|
70
|
+
public:
|
71
|
+
PickFirstSubchannelData(PickFirstSubchannelList* subchannel_list,
|
72
|
+
const grpc_lb_user_data_vtable* user_data_vtable,
|
73
|
+
const grpc_lb_address& address,
|
74
|
+
grpc_subchannel* subchannel,
|
75
|
+
grpc_combiner* combiner)
|
76
|
+
: SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
|
77
|
+
combiner) {}
|
78
|
+
|
79
|
+
void ProcessConnectivityChangeLocked(
|
80
|
+
grpc_connectivity_state connectivity_state, grpc_error* error) override;
|
81
|
+
};
|
82
|
+
|
83
|
+
class PickFirstSubchannelList
|
84
|
+
: public SubchannelList<PickFirstSubchannelList,
|
85
|
+
PickFirstSubchannelData> {
|
86
|
+
public:
|
87
|
+
PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer,
|
88
|
+
const grpc_lb_addresses* addresses,
|
89
|
+
grpc_combiner* combiner,
|
90
|
+
grpc_client_channel_factory* client_channel_factory,
|
91
|
+
const grpc_channel_args& args)
|
92
|
+
: SubchannelList(policy, tracer, addresses, combiner,
|
93
|
+
client_channel_factory, args) {
|
94
|
+
// Need to maintain a ref to the LB policy as long as we maintain
|
95
|
+
// any references to subchannels, since the subchannels'
|
96
|
+
// pollset_sets will include the LB policy's pollset_set.
|
97
|
+
policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
|
98
|
+
}
|
99
|
+
|
100
|
+
~PickFirstSubchannelList() {
|
101
|
+
PickFirst* p = static_cast<PickFirst*>(policy());
|
102
|
+
p->Unref(DEBUG_LOCATION, "subchannel_list");
|
103
|
+
}
|
104
|
+
};
|
105
|
+
|
65
106
|
void ShutdownLocked() override;
|
66
107
|
|
67
108
|
void StartPickingLocked();
|
68
109
|
void DestroyUnselectedSubchannelsLocked();
|
69
110
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
/** all our subchannels */
|
78
|
-
grpc_lb_subchannel_list* subchannel_list_ = nullptr;
|
79
|
-
/** latest pending subchannel list */
|
80
|
-
grpc_lb_subchannel_list* latest_pending_subchannel_list_ = nullptr;
|
81
|
-
/** selected subchannel in \a subchannel_list */
|
82
|
-
grpc_lb_subchannel_data* selected_ = nullptr;
|
83
|
-
/** have we started picking? */
|
111
|
+
// All our subchannels.
|
112
|
+
OrphanablePtr<PickFirstSubchannelList> subchannel_list_;
|
113
|
+
// Latest pending subchannel list.
|
114
|
+
OrphanablePtr<PickFirstSubchannelList> latest_pending_subchannel_list_;
|
115
|
+
// Selected subchannel in \a subchannel_list_.
|
116
|
+
PickFirstSubchannelData* selected_ = nullptr;
|
117
|
+
// Have we started picking?
|
84
118
|
bool started_picking_ = false;
|
85
|
-
|
119
|
+
// Are we shut down?
|
86
120
|
bool shutdown_ = false;
|
87
|
-
|
121
|
+
// List of picks that are waiting on connectivity.
|
88
122
|
PickState* pending_picks_ = nullptr;
|
89
|
-
|
123
|
+
// Our connectivity state tracker.
|
90
124
|
grpc_connectivity_state_tracker state_tracker_;
|
91
125
|
};
|
92
126
|
|
@@ -95,7 +129,7 @@ PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) {
|
|
95
129
|
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
|
96
130
|
"pick_first");
|
97
131
|
if (grpc_lb_pick_first_trace.enabled()) {
|
98
|
-
gpr_log(
|
132
|
+
gpr_log(GPR_INFO, "Pick First %p created.", this);
|
99
133
|
}
|
100
134
|
UpdateLocked(*args.args);
|
101
135
|
grpc_subchannel_index_ref();
|
@@ -103,7 +137,7 @@ PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) {
|
|
103
137
|
|
104
138
|
PickFirst::~PickFirst() {
|
105
139
|
if (grpc_lb_pick_first_trace.enabled()) {
|
106
|
-
gpr_log(
|
140
|
+
gpr_log(GPR_INFO, "Destroying Pick First %p", this);
|
107
141
|
}
|
108
142
|
GPR_ASSERT(subchannel_list_ == nullptr);
|
109
143
|
GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
|
@@ -126,7 +160,7 @@ void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
|
|
126
160
|
void PickFirst::ShutdownLocked() {
|
127
161
|
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
|
128
162
|
if (grpc_lb_pick_first_trace.enabled()) {
|
129
|
-
gpr_log(
|
163
|
+
gpr_log(GPR_INFO, "Pick First %p Shutting down", this);
|
130
164
|
}
|
131
165
|
shutdown_ = true;
|
132
166
|
PickState* pick;
|
@@ -137,15 +171,8 @@ void PickFirst::ShutdownLocked() {
|
|
137
171
|
}
|
138
172
|
grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
|
139
173
|
GRPC_ERROR_REF(error), "shutdown");
|
140
|
-
|
141
|
-
|
142
|
-
subchannel_list_ = nullptr;
|
143
|
-
}
|
144
|
-
if (latest_pending_subchannel_list_ != nullptr) {
|
145
|
-
grpc_lb_subchannel_list_shutdown_and_unref(latest_pending_subchannel_list_,
|
146
|
-
"pf_shutdown");
|
147
|
-
latest_pending_subchannel_list_ = nullptr;
|
148
|
-
}
|
174
|
+
subchannel_list_.reset();
|
175
|
+
latest_pending_subchannel_list_.reset();
|
149
176
|
TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED);
|
150
177
|
GRPC_ERROR_UNREF(error);
|
151
178
|
}
|
@@ -192,14 +219,10 @@ void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
|
|
192
219
|
|
193
220
|
void PickFirst::StartPickingLocked() {
|
194
221
|
started_picking_ = true;
|
195
|
-
if (subchannel_list_ != nullptr
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
SubchannelListRefForConnectivityWatch(
|
200
|
-
subchannel_list_, "connectivity_watch+start_picking");
|
201
|
-
grpc_lb_subchannel_data_start_connectivity_watch(
|
202
|
-
&subchannel_list_->subchannels[i]);
|
222
|
+
if (subchannel_list_ != nullptr) {
|
223
|
+
for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) {
|
224
|
+
if (subchannel_list_->subchannel(i)->subchannel() != nullptr) {
|
225
|
+
subchannel_list_->subchannel(i)->StartConnectivityWatchLocked();
|
203
226
|
break;
|
204
227
|
}
|
205
228
|
}
|
@@ -215,7 +238,7 @@ void PickFirst::ExitIdleLocked() {
|
|
215
238
|
bool PickFirst::PickLocked(PickState* pick) {
|
216
239
|
// If we have a selected subchannel already, return synchronously.
|
217
240
|
if (selected_ != nullptr) {
|
218
|
-
pick->connected_subchannel = selected_->connected_subchannel;
|
241
|
+
pick->connected_subchannel = selected_->connected_subchannel()->Ref();
|
219
242
|
return true;
|
220
243
|
}
|
221
244
|
// No subchannel selected yet, so handle asynchronously.
|
@@ -228,11 +251,10 @@ bool PickFirst::PickLocked(PickState* pick) {
|
|
228
251
|
}
|
229
252
|
|
230
253
|
void PickFirst::DestroyUnselectedSubchannelsLocked() {
|
231
|
-
for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
|
232
|
-
|
254
|
+
for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) {
|
255
|
+
PickFirstSubchannelData* sd = subchannel_list_->subchannel(i);
|
233
256
|
if (selected_ != sd) {
|
234
|
-
|
235
|
-
"selected_different_subchannel");
|
257
|
+
sd->UnrefSubchannelLocked("selected_different_subchannel");
|
236
258
|
}
|
237
259
|
}
|
238
260
|
}
|
@@ -249,7 +271,7 @@ void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
|
|
249
271
|
|
250
272
|
void PickFirst::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
|
251
273
|
if (selected_ != nullptr) {
|
252
|
-
selected_->connected_subchannel->Ping(on_initiate, on_ack);
|
274
|
+
selected_->connected_subchannel()->Ping(on_initiate, on_ack);
|
253
275
|
} else {
|
254
276
|
GRPC_CLOSURE_SCHED(on_initiate,
|
255
277
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
|
@@ -258,24 +280,6 @@ void PickFirst::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
|
|
258
280
|
}
|
259
281
|
}
|
260
282
|
|
261
|
-
void PickFirst::SubchannelListRefForConnectivityWatch(
|
262
|
-
grpc_lb_subchannel_list* subchannel_list, const char* reason) {
|
263
|
-
// TODO(roth): We currently track this ref manually. Once the new
|
264
|
-
// ClosureRef API is ready and the subchannel_list code has been
|
265
|
-
// converted to a C++ API, find a way to hold the RefCountedPtr<>
|
266
|
-
// somewhere (maybe in the subchannel_data object) instead of doing
|
267
|
-
// this manually.
|
268
|
-
auto self = Ref(DEBUG_LOCATION, reason);
|
269
|
-
self.release();
|
270
|
-
grpc_lb_subchannel_list_ref(subchannel_list, reason);
|
271
|
-
}
|
272
|
-
|
273
|
-
void PickFirst::SubchannelListUnrefForConnectivityWatch(
|
274
|
-
grpc_lb_subchannel_list* subchannel_list, const char* reason) {
|
275
|
-
Unref(DEBUG_LOCATION, reason);
|
276
|
-
grpc_lb_subchannel_list_unref(subchannel_list, reason);
|
277
|
-
}
|
278
|
-
|
279
283
|
void PickFirst::UpdateLocked(const grpc_channel_args& args) {
|
280
284
|
const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
|
281
285
|
if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
|
@@ -295,75 +299,67 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
|
|
295
299
|
return;
|
296
300
|
}
|
297
301
|
const grpc_lb_addresses* addresses =
|
298
|
-
|
302
|
+
static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
|
299
303
|
if (grpc_lb_pick_first_trace.enabled()) {
|
300
304
|
gpr_log(GPR_INFO,
|
301
305
|
"Pick First %p received update with %" PRIuPTR " addresses", this,
|
302
306
|
addresses->num_addresses);
|
303
307
|
}
|
304
|
-
|
308
|
+
auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
|
305
309
|
this, &grpc_lb_pick_first_trace, addresses, combiner(),
|
306
|
-
client_channel_factory(), args
|
307
|
-
if (subchannel_list->num_subchannels == 0) {
|
310
|
+
client_channel_factory(), args);
|
311
|
+
if (subchannel_list->num_subchannels() == 0) {
|
308
312
|
// Empty update or no valid subchannels. Unsubscribe from all current
|
309
313
|
// subchannels and put the channel in TRANSIENT_FAILURE.
|
310
314
|
grpc_connectivity_state_set(
|
311
315
|
&state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
312
316
|
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
|
313
317
|
"pf_update_empty");
|
314
|
-
|
315
|
-
grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
|
316
|
-
"sl_shutdown_empty_update");
|
317
|
-
}
|
318
|
-
subchannel_list_ = subchannel_list; // Empty list.
|
318
|
+
subchannel_list_ = std::move(subchannel_list); // Empty list.
|
319
319
|
selected_ = nullptr;
|
320
320
|
return;
|
321
321
|
}
|
322
322
|
if (selected_ == nullptr) {
|
323
323
|
// We don't yet have a selected subchannel, so replace the current
|
324
324
|
// subchannel list immediately.
|
325
|
-
|
326
|
-
|
327
|
-
|
325
|
+
subchannel_list_ = std::move(subchannel_list);
|
326
|
+
// If we've started picking, start trying to connect to the first
|
327
|
+
// subchannel in the new list.
|
328
|
+
if (started_picking_) {
|
329
|
+
subchannel_list_->subchannel(0)->StartConnectivityWatchLocked();
|
328
330
|
}
|
329
|
-
subchannel_list_ = subchannel_list;
|
330
331
|
} else {
|
331
332
|
// We do have a selected subchannel.
|
332
333
|
// Check if it's present in the new list. If so, we're done.
|
333
|
-
for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
|
334
|
-
|
335
|
-
if (sd->subchannel == selected_->subchannel) {
|
334
|
+
for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
|
335
|
+
PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
|
336
|
+
if (sd->subchannel() == selected_->subchannel()) {
|
336
337
|
// The currently selected subchannel is in the update: we are done.
|
337
338
|
if (grpc_lb_pick_first_trace.enabled()) {
|
338
339
|
gpr_log(GPR_INFO,
|
339
340
|
"Pick First %p found already selected subchannel %p "
|
340
341
|
"at update index %" PRIuPTR " of %" PRIuPTR "; update done",
|
341
|
-
this, selected_->subchannel, i,
|
342
|
-
subchannel_list->num_subchannels);
|
343
|
-
}
|
344
|
-
if (selected_->connected_subchannel != nullptr) {
|
345
|
-
sd->connected_subchannel = selected_->connected_subchannel;
|
342
|
+
this, selected_->subchannel(), i,
|
343
|
+
subchannel_list->num_subchannels());
|
346
344
|
}
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
345
|
+
// Make sure it's in state READY. It might not be if we grabbed
|
346
|
+
// the combiner while a connectivity state notification
|
347
|
+
// informing us otherwise is pending.
|
348
|
+
// Note that CheckConnectivityStateLocked() also takes a ref to
|
349
|
+
// the connected subchannel.
|
350
|
+
grpc_error* error = GRPC_ERROR_NONE;
|
351
|
+
if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) {
|
352
|
+
selected_ = sd;
|
353
|
+
subchannel_list_ = std::move(subchannel_list);
|
354
|
+
DestroyUnselectedSubchannelsLocked();
|
355
|
+
sd->StartConnectivityWatchLocked();
|
356
|
+
// If there was a previously pending update (which may or may
|
357
|
+
// not have contained the currently selected subchannel), drop
|
358
|
+
// it, so that it doesn't override what we've done here.
|
359
|
+
latest_pending_subchannel_list_.reset();
|
360
|
+
return;
|
351
361
|
}
|
352
|
-
|
353
|
-
DestroyUnselectedSubchannelsLocked();
|
354
|
-
SubchannelListRefForConnectivityWatch(
|
355
|
-
subchannel_list, "connectivity_watch+replace_selected");
|
356
|
-
grpc_lb_subchannel_data_start_connectivity_watch(sd);
|
357
|
-
// If there was a previously pending update (which may or may
|
358
|
-
// not have contained the currently selected subchannel), drop
|
359
|
-
// it, so that it doesn't override what we've done here.
|
360
|
-
if (latest_pending_subchannel_list_ != nullptr) {
|
361
|
-
grpc_lb_subchannel_list_shutdown_and_unref(
|
362
|
-
latest_pending_subchannel_list_,
|
363
|
-
"pf_update_includes_selected+outdated");
|
364
|
-
latest_pending_subchannel_list_ = nullptr;
|
365
|
-
}
|
366
|
-
return;
|
362
|
+
GRPC_ERROR_UNREF(error);
|
367
363
|
}
|
368
364
|
}
|
369
365
|
// Not keeping the previous selected subchannel, so set the latest
|
@@ -372,88 +368,66 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
|
|
372
368
|
// subchannel list.
|
373
369
|
if (latest_pending_subchannel_list_ != nullptr) {
|
374
370
|
if (grpc_lb_pick_first_trace.enabled()) {
|
375
|
-
gpr_log(
|
371
|
+
gpr_log(GPR_INFO,
|
376
372
|
"Pick First %p Shutting down latest pending subchannel list "
|
377
373
|
"%p, about to be replaced by newer latest %p",
|
378
|
-
this, latest_pending_subchannel_list_,
|
374
|
+
this, latest_pending_subchannel_list_.get(),
|
375
|
+
subchannel_list.get());
|
379
376
|
}
|
380
|
-
grpc_lb_subchannel_list_shutdown_and_unref(
|
381
|
-
latest_pending_subchannel_list_, "sl_outdated_dont_smash");
|
382
377
|
}
|
383
|
-
latest_pending_subchannel_list_ = subchannel_list;
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
grpc_lb_subchannel_data_start_connectivity_watch(
|
391
|
-
&subchannel_list->subchannels[0]);
|
378
|
+
latest_pending_subchannel_list_ = std::move(subchannel_list);
|
379
|
+
// If we've started picking, start trying to connect to the first
|
380
|
+
// subchannel in the new list.
|
381
|
+
if (started_picking_) {
|
382
|
+
latest_pending_subchannel_list_->subchannel(0)
|
383
|
+
->StartConnectivityWatchLocked();
|
384
|
+
}
|
392
385
|
}
|
393
386
|
}
|
394
387
|
|
395
|
-
void PickFirst::
|
396
|
-
|
397
|
-
PickFirst* p = static_cast<PickFirst*>(
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
"), subchannel_list %p: state=%s p->shutdown_=%d "
|
403
|
-
"sd->subchannel_list->shutting_down=%d error=%s",
|
404
|
-
p, sd->subchannel, sd->subchannel_list->checking_subchannel,
|
405
|
-
sd->subchannel_list->num_subchannels, sd->subchannel_list,
|
406
|
-
grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe),
|
407
|
-
p->shutdown_, sd->subchannel_list->shutting_down,
|
408
|
-
grpc_error_string(error));
|
409
|
-
}
|
410
|
-
// If the policy is shutting down, unref and return.
|
411
|
-
if (p->shutdown_) {
|
412
|
-
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
|
413
|
-
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_shutdown");
|
414
|
-
p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
|
415
|
-
"pf_shutdown");
|
416
|
-
return;
|
417
|
-
}
|
418
|
-
// If the subchannel list is shutting down, stop watching.
|
419
|
-
if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
|
420
|
-
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
|
421
|
-
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_sl_shutdown");
|
422
|
-
p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
|
423
|
-
"pf_sl_shutdown");
|
424
|
-
return;
|
425
|
-
}
|
426
|
-
// If we're still here, the notification must be for a subchannel in
|
427
|
-
// either the current or latest pending subchannel lists.
|
428
|
-
GPR_ASSERT(sd->subchannel_list == p->subchannel_list_ ||
|
429
|
-
sd->subchannel_list == p->latest_pending_subchannel_list_);
|
430
|
-
// Update state.
|
431
|
-
sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
|
388
|
+
void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
|
389
|
+
grpc_connectivity_state connectivity_state, grpc_error* error) {
|
390
|
+
PickFirst* p = static_cast<PickFirst*>(subchannel_list()->policy());
|
391
|
+
// The notification must be for a subchannel in either the current or
|
392
|
+
// latest pending subchannel lists.
|
393
|
+
GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() ||
|
394
|
+
subchannel_list() == p->latest_pending_subchannel_list_.get());
|
432
395
|
// Handle updates for the currently selected subchannel.
|
433
|
-
if (p->selected_ ==
|
396
|
+
if (p->selected_ == this) {
|
397
|
+
if (grpc_lb_pick_first_trace.enabled()) {
|
398
|
+
gpr_log(GPR_INFO,
|
399
|
+
"Pick First %p connectivity changed for selected subchannel", p);
|
400
|
+
}
|
434
401
|
// If the new state is anything other than READY and there is a
|
435
402
|
// pending update, switch to the pending update.
|
436
|
-
if (
|
403
|
+
if (connectivity_state != GRPC_CHANNEL_READY &&
|
437
404
|
p->latest_pending_subchannel_list_ != nullptr) {
|
405
|
+
if (grpc_lb_pick_first_trace.enabled()) {
|
406
|
+
gpr_log(GPR_INFO,
|
407
|
+
"Pick First %p promoting pending subchannel list %p to "
|
408
|
+
"replace %p",
|
409
|
+
p, p->latest_pending_subchannel_list_.get(),
|
410
|
+
p->subchannel_list_.get());
|
411
|
+
}
|
438
412
|
p->selected_ = nullptr;
|
439
|
-
|
440
|
-
p->
|
441
|
-
sd->subchannel_list, "selected_not_ready+switch_to_update");
|
442
|
-
grpc_lb_subchannel_list_shutdown_and_unref(
|
443
|
-
p->subchannel_list_, "selected_not_ready+switch_to_update");
|
444
|
-
p->subchannel_list_ = p->latest_pending_subchannel_list_;
|
445
|
-
p->latest_pending_subchannel_list_ = nullptr;
|
413
|
+
StopConnectivityWatchLocked();
|
414
|
+
p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
|
446
415
|
grpc_connectivity_state_set(
|
447
416
|
&p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
448
|
-
|
417
|
+
error != GRPC_ERROR_NONE
|
418
|
+
? GRPC_ERROR_REF(error)
|
419
|
+
: GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
420
|
+
"selected subchannel not ready; switching to pending "
|
421
|
+
"update"),
|
422
|
+
"selected_not_ready+switch_to_update");
|
449
423
|
} else {
|
450
424
|
// TODO(juanlishen): we re-resolve when the selected subchannel goes to
|
451
425
|
// TRANSIENT_FAILURE because we used to shut down in this case before
|
452
426
|
// re-resolution is introduced. But we need to investigate whether we
|
453
427
|
// really want to take any action instead of waiting for the selected
|
454
428
|
// subchannel reconnecting.
|
455
|
-
GPR_ASSERT(
|
456
|
-
if (
|
429
|
+
GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN);
|
430
|
+
if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
|
457
431
|
// If the selected channel goes bad, request a re-resolution.
|
458
432
|
grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE,
|
459
433
|
GRPC_ERROR_NONE,
|
@@ -462,19 +436,16 @@ void PickFirst::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
|
|
462
436
|
p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE);
|
463
437
|
// In transient failure. Rely on re-resolution to recover.
|
464
438
|
p->selected_ = nullptr;
|
465
|
-
|
466
|
-
|
467
|
-
"pf_selected_shutdown");
|
468
|
-
grpc_lb_subchannel_data_unref_subchannel(
|
469
|
-
sd, "pf_selected_shutdown"); // Unrefs connected subchannel
|
439
|
+
UnrefSubchannelLocked("pf_selected_shutdown");
|
440
|
+
StopConnectivityWatchLocked();
|
470
441
|
} else {
|
471
|
-
grpc_connectivity_state_set(&p->state_tracker_,
|
472
|
-
sd->curr_connectivity_state,
|
442
|
+
grpc_connectivity_state_set(&p->state_tracker_, connectivity_state,
|
473
443
|
GRPC_ERROR_REF(error), "selected_changed");
|
474
444
|
// Renew notification.
|
475
|
-
|
445
|
+
RenewConnectivityWatchLocked();
|
476
446
|
}
|
477
447
|
}
|
448
|
+
GRPC_ERROR_UNREF(error);
|
478
449
|
return;
|
479
450
|
}
|
480
451
|
// If we get here, there are two possible cases:
|
@@ -486,26 +457,27 @@ void PickFirst::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
|
|
486
457
|
// for a subchannel in p->latest_pending_subchannel_list_. The
|
487
458
|
// goal here is to find a subchannel from the update that we can
|
488
459
|
// select in place of the current one.
|
489
|
-
switch (
|
460
|
+
switch (connectivity_state) {
|
490
461
|
case GRPC_CHANNEL_READY: {
|
491
462
|
// Case 2. Promote p->latest_pending_subchannel_list_ to
|
492
463
|
// p->subchannel_list_.
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
464
|
+
if (subchannel_list() == p->latest_pending_subchannel_list_.get()) {
|
465
|
+
if (grpc_lb_pick_first_trace.enabled()) {
|
466
|
+
gpr_log(GPR_INFO,
|
467
|
+
"Pick First %p promoting pending subchannel list %p to "
|
468
|
+
"replace %p",
|
469
|
+
p, p->latest_pending_subchannel_list_.get(),
|
470
|
+
p->subchannel_list_.get());
|
471
|
+
}
|
472
|
+
p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
|
501
473
|
}
|
502
474
|
// Cases 1 and 2.
|
503
475
|
grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY,
|
504
476
|
GRPC_ERROR_NONE, "connecting_ready");
|
505
|
-
p->selected_ =
|
477
|
+
p->selected_ = this;
|
506
478
|
if (grpc_lb_pick_first_trace.enabled()) {
|
507
479
|
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p,
|
508
|
-
|
480
|
+
subchannel());
|
509
481
|
}
|
510
482
|
// Drop all other subchannels, since we are now connected.
|
511
483
|
p->DestroyUnselectedSubchannelsLocked();
|
@@ -513,7 +485,8 @@ void PickFirst::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
|
|
513
485
|
PickState* pick;
|
514
486
|
while ((pick = p->pending_picks_)) {
|
515
487
|
p->pending_picks_ = pick->next;
|
516
|
-
pick->connected_subchannel =
|
488
|
+
pick->connected_subchannel =
|
489
|
+
p->selected_->connected_subchannel()->Ref();
|
517
490
|
if (grpc_lb_pick_first_trace.enabled()) {
|
518
491
|
gpr_log(GPR_INFO,
|
519
492
|
"Servicing pending pick with selected subchannel %p",
|
@@ -522,45 +495,43 @@ void PickFirst::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
|
|
522
495
|
GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
|
523
496
|
}
|
524
497
|
// Renew notification.
|
525
|
-
|
498
|
+
RenewConnectivityWatchLocked();
|
526
499
|
break;
|
527
500
|
}
|
528
501
|
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
|
529
|
-
|
502
|
+
StopConnectivityWatchLocked();
|
503
|
+
PickFirstSubchannelData* sd = this;
|
530
504
|
do {
|
531
|
-
|
532
|
-
(sd->
|
533
|
-
|
534
|
-
|
535
|
-
->subchannels[sd->subchannel_list->checking_subchannel];
|
536
|
-
} while (sd->subchannel == nullptr);
|
505
|
+
size_t next_index =
|
506
|
+
(sd->Index() + 1) % subchannel_list()->num_subchannels();
|
507
|
+
sd = subchannel_list()->subchannel(next_index);
|
508
|
+
} while (sd->subchannel() == nullptr);
|
537
509
|
// Case 1: Only set state to TRANSIENT_FAILURE if we've tried
|
538
510
|
// all subchannels.
|
539
|
-
if (sd->
|
540
|
-
sd->subchannel_list == p->subchannel_list_) {
|
511
|
+
if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) {
|
541
512
|
grpc_connectivity_state_set(
|
542
513
|
&p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
543
514
|
GRPC_ERROR_REF(error), "connecting_transient_failure");
|
544
515
|
}
|
545
|
-
|
546
|
-
grpc_lb_subchannel_data_start_connectivity_watch(sd);
|
516
|
+
sd->StartConnectivityWatchLocked();
|
547
517
|
break;
|
548
518
|
}
|
549
519
|
case GRPC_CHANNEL_CONNECTING:
|
550
520
|
case GRPC_CHANNEL_IDLE: {
|
551
521
|
// Only update connectivity state in case 1.
|
552
|
-
if (
|
522
|
+
if (subchannel_list() == p->subchannel_list_.get()) {
|
553
523
|
grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING,
|
554
524
|
GRPC_ERROR_REF(error),
|
555
525
|
"connecting_changed");
|
556
526
|
}
|
557
527
|
// Renew notification.
|
558
|
-
|
528
|
+
RenewConnectivityWatchLocked();
|
559
529
|
break;
|
560
530
|
}
|
561
531
|
case GRPC_CHANNEL_SHUTDOWN:
|
562
532
|
GPR_UNREACHABLE_CODE(break);
|
563
533
|
}
|
534
|
+
GRPC_ERROR_UNREF(error);
|
564
535
|
}
|
565
536
|
|
566
537
|
//
|