mirror of https://github.com/grpc/grpc.git
commit
6d5c2c250d
412 changed files with 13334 additions and 10465 deletions
@ -0,0 +1,108 @@ |
|||||||
|
[VARIABLES] |
||||||
|
|
||||||
|
# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection |
||||||
|
# not include "unused_" and "ignored_" by default? |
||||||
|
dummy-variables-rgx=^ignored_|^unused_ |
||||||
|
|
||||||
|
[DESIGN] |
||||||
|
|
||||||
|
# NOTE(nathaniel): Not particularly attached to this value; it just seems to |
||||||
|
# be what works for us at the moment (excepting the dead-code-walking Beta |
||||||
|
# API). |
||||||
|
max-args=6 |
||||||
|
|
||||||
|
[MISCELLANEOUS] |
||||||
|
|
||||||
|
# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and |
||||||
|
# "NOTE(<username or issue link>): ". We do not allow "TODO:", |
||||||
|
# "TODO(<username>):", "FIXME:", or anything else. |
||||||
|
notes=FIXME,XXX |
||||||
|
|
||||||
|
[MESSAGES CONTROL] |
||||||
|
|
||||||
|
disable= |
||||||
|
# These suppressions are specific to tests: |
||||||
|
# |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/261): investigate |
||||||
|
# each of the following one by one and consider eliminating |
||||||
|
# the suppression category. |
||||||
|
# Eventually, the hope is to eliminate the .pylintrc-tests |
||||||
|
# altogether and rely on .pylintrc for everything. |
||||||
|
pointless-statement, |
||||||
|
no-member, |
||||||
|
no-self-use, |
||||||
|
attribute-defined-outside-init, |
||||||
|
unused-argument, |
||||||
|
unused-variable, |
||||||
|
unused-import, |
||||||
|
redefined-builtin, |
||||||
|
too-many-public-methods, |
||||||
|
too-many-locals, |
||||||
|
redefined-variable-type, |
||||||
|
redefined-outer-name, |
||||||
|
ungrouped-imports, |
||||||
|
too-many-branches, |
||||||
|
too-many-arguments, |
||||||
|
too-many-format-args, |
||||||
|
too-many-return-statements, |
||||||
|
too-many-statements, |
||||||
|
line-too-long, |
||||||
|
wrong-import-position, |
||||||
|
wrong-import-order, |
||||||
|
# -- END OF TEST-SPECIFIC SUPPRESSIONS -- |
||||||
|
|
||||||
|
|
||||||
|
# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279): |
||||||
|
# Enable cyclic-import after a 1.7-or-later pylint release that |
||||||
|
# recognizes our disable=cyclic-import suppressions. |
||||||
|
cyclic-import, |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/8622): Enable this after the |
||||||
|
# Beta API is removed. |
||||||
|
duplicate-code, |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/261): Doesn't seem to |
||||||
|
# understand enum and concurrent.futures; look into this later with the |
||||||
|
# latest pylint version. |
||||||
|
import-error, |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/261): Enable this one. |
||||||
|
# Should take a little configuration but not much. |
||||||
|
invalid-name, |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/261): This doesn't seem to |
||||||
|
# work for now? Try with a later pylint? |
||||||
|
locally-disabled, |
||||||
|
# NOTE(nathaniel): What even is this? *Enabling* an inspection results |
||||||
|
# in a warning? How does that encourage more analysis and coverage? |
||||||
|
locally-enabled, |
||||||
|
# NOTE(nathaniel): We don't write doc strings for most private code |
||||||
|
# elements. |
||||||
|
missing-docstring, |
||||||
|
# NOTE(nathaniel): In numeric comparisons it is better to have the |
||||||
|
# lesser (or lesser-or-equal-to) quantity on the left when the |
||||||
|
# expression is true than it is to worry about which is an identifier |
||||||
|
# and which a literal value. |
||||||
|
misplaced-comparison-constant, |
||||||
|
# NOTE(nathaniel): Our completely abstract interface classes don't have |
||||||
|
# constructors. |
||||||
|
no-init, |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/261): Doesn't yet play |
||||||
|
# nicely with some of our code being implemented in Cython. Maybe in a |
||||||
|
# later version? |
||||||
|
no-name-in-module, |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/261): Suppress these where |
||||||
|
# the odd shape of the authentication portion of the API forces them on |
||||||
|
# us and enable everywhere else. |
||||||
|
protected-access, |
||||||
|
# NOTE(nathaniel): Pylint and I will probably never agree on this. |
||||||
|
too-few-public-methods, |
||||||
|
# NOTE(nathaniel): Pylint and I wil probably never agree on this for |
||||||
|
# private classes. For public classes maybe? |
||||||
|
too-many-instance-attributes, |
||||||
|
# NOTE(nathaniel): Some of our modules have a lot of lines... of |
||||||
|
# specification and documentation. Maybe if this were |
||||||
|
# lines-of-code-based we would use it. |
||||||
|
too-many-lines, |
||||||
|
# TODO(https://github.com/grpc/grpc/issues/261): Maybe we could have |
||||||
|
# this one if we extracted just a few more helper functions... |
||||||
|
too-many-nested-blocks, |
||||||
|
# NOTE(nathaniel): I have disputed the premise of this inspection from |
||||||
|
# the beginning and will continue to do so until it goes away for good. |
||||||
|
useless-else-on-loop, |
@ -1,18 +1,15 @@ |
|||||||
Each version of gRPC gets a new description of what the 'g' stands for, since |
'g' stands for something different every gRPC release: |
||||||
we've never really been able to figure it out. |
|
||||||
|
|
||||||
Below is a list of already-used definitions (that should not be repeated in the |
- 1.0 'g' stands for ['gRPC'](https://github.com/grpc/grpc/tree/v1.0.x) |
||||||
future), and the corresponding version numbers that used them: |
- 1.1 'g' stands for ['good'](https://github.com/grpc/grpc/tree/v1.1.x) |
||||||
|
- 1.2 'g' stands for ['green'](https://github.com/grpc/grpc/tree/v1.2.x) |
||||||
- 1.0 'g' stands for 'gRPC' |
- 1.3 'g' stands for ['gentle'](https://github.com/grpc/grpc/tree/v1.3.x) |
||||||
- 1.1 'g' stands for 'good' |
- 1.4 'g' stands for ['gregarious'](https://github.com/grpc/grpc/tree/v1.4.x) |
||||||
- 1.2 'g' stands for 'green' |
- 1.6 'g' stands for ['garcia'](https://github.com/grpc/grpc/tree/v1.6.x) |
||||||
- 1.3 'g' stands for 'gentle' |
- 1.7 'g' stands for ['gambit'](https://github.com/grpc/grpc/tree/v1.7.x) |
||||||
- 1.4 'g' stands for 'gregarious' |
- 1.8 'g' stands for ['generous'](https://github.com/grpc/grpc/tree/v1.8.x) |
||||||
- 1.6 'g' stands for 'garcia' |
- 1.9 'g' stands for ['glossy'](https://github.com/grpc/grpc/tree/v1.9.x) |
||||||
- 1.7 'g' stands for 'gambit' |
- 1.10 'g' stands for ['glamorous'](https://github.com/grpc/grpc/tree/v1.10.x) |
||||||
- 1.8 'g' stands for 'generous' |
- 1.11 'g' stands for ['gorgeous'](https://github.com/grpc/grpc/tree/v1.11.x) |
||||||
- 1.9 'g' stands for 'glossy' |
- 1.12 'g' stands for ['glorious'](https://github.com/grpc/grpc/tree/v1.12.x) |
||||||
- 1.10 'g' stands for 'glamorous' |
- 1.13 'g' stands for ['gloriosa'](https://github.com/grpc/grpc/tree/master) |
||||||
- 1.11 'g' stands for 'gorgeous' |
|
||||||
- 1.12 'g' stands for 'glorious' |
|
||||||
|
@ -1,5 +0,0 @@ |
|||||||
{ |
|
||||||
"sdk": { |
|
||||||
"version": "1.0.0" |
|
||||||
} |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2018 gRPC authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H |
||||||
|
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H |
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
|
||||||
|
/** Channel arg indicating if a target corresponding to the address is grpclb
|
||||||
|
* loadbalancer. The type of this arg is an integer and the value is treated as |
||||||
|
* a bool. */ |
||||||
|
#define GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER \ |
||||||
|
"grpc.address_is_grpclb_load_balancer" |
||||||
|
/** Channel arg indicating if a target corresponding to the address is a backend
|
||||||
|
* received from a balancer. The type of this arg is an integer and the value is |
||||||
|
* treated as a bool. */ |
||||||
|
#define GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER \ |
||||||
|
"grpc.address_is_backend_from_grpclb_load_balancer" |
||||||
|
|
||||||
|
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H \ |
||||||
|
*/ |
@ -1,253 +0,0 @@ |
|||||||
/*
|
|
||||||
* |
|
||||||
* Copyright 2015 gRPC authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <grpc/support/port_platform.h> |
|
||||||
|
|
||||||
#include <string.h> |
|
||||||
|
|
||||||
#include <grpc/support/alloc.h> |
|
||||||
|
|
||||||
#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" |
|
||||||
#include "src/core/lib/channel/channel_args.h" |
|
||||||
#include "src/core/lib/debug/trace.h" |
|
||||||
#include "src/core/lib/iomgr/closure.h" |
|
||||||
#include "src/core/lib/iomgr/combiner.h" |
|
||||||
#include "src/core/lib/iomgr/sockaddr_utils.h" |
|
||||||
#include "src/core/lib/transport/connectivity_state.h" |
|
||||||
|
|
||||||
void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd, |
|
||||||
const char* reason) { |
|
||||||
if (sd->subchannel != nullptr) { |
|
||||||
if (sd->subchannel_list->tracer->enabled()) { |
|
||||||
gpr_log(GPR_DEBUG, |
|
||||||
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR |
|
||||||
" (subchannel %p): unreffing subchannel", |
|
||||||
sd->subchannel_list->tracer->name(), sd->subchannel_list->policy, |
|
||||||
sd->subchannel_list, |
|
||||||
static_cast<size_t>(sd - sd->subchannel_list->subchannels), |
|
||||||
sd->subchannel_list->num_subchannels, sd->subchannel); |
|
||||||
} |
|
||||||
GRPC_SUBCHANNEL_UNREF(sd->subchannel, reason); |
|
||||||
sd->subchannel = nullptr; |
|
||||||
sd->connected_subchannel.reset(); |
|
||||||
if (sd->user_data != nullptr) { |
|
||||||
GPR_ASSERT(sd->user_data_vtable != nullptr); |
|
||||||
sd->user_data_vtable->destroy(sd->user_data); |
|
||||||
sd->user_data = nullptr; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void grpc_lb_subchannel_data_start_connectivity_watch( |
|
||||||
grpc_lb_subchannel_data* sd) { |
|
||||||
if (sd->subchannel_list->tracer->enabled()) { |
|
||||||
gpr_log( |
|
||||||
GPR_DEBUG, |
|
||||||
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR |
|
||||||
" (subchannel %p): requesting connectivity change " |
|
||||||
"notification (from %s)", |
|
||||||
sd->subchannel_list->tracer->name(), sd->subchannel_list->policy, |
|
||||||
sd->subchannel_list, |
|
||||||
static_cast<size_t>(sd - sd->subchannel_list->subchannels), |
|
||||||
sd->subchannel_list->num_subchannels, sd->subchannel, |
|
||||||
grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe)); |
|
||||||
} |
|
||||||
sd->connectivity_notification_pending = true; |
|
||||||
grpc_subchannel_notify_on_state_change( |
|
||||||
sd->subchannel, sd->subchannel_list->policy->interested_parties(), |
|
||||||
&sd->pending_connectivity_state_unsafe, |
|
||||||
&sd->connectivity_changed_closure); |
|
||||||
} |
|
||||||
|
|
||||||
void grpc_lb_subchannel_data_stop_connectivity_watch( |
|
||||||
grpc_lb_subchannel_data* sd) { |
|
||||||
if (sd->subchannel_list->tracer->enabled()) { |
|
||||||
gpr_log(GPR_DEBUG, |
|
||||||
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR |
|
||||||
" (subchannel %p): stopping connectivity watch", |
|
||||||
sd->subchannel_list->tracer->name(), sd->subchannel_list->policy, |
|
||||||
sd->subchannel_list, |
|
||||||
static_cast<size_t>(sd - sd->subchannel_list->subchannels), |
|
||||||
sd->subchannel_list->num_subchannels, sd->subchannel); |
|
||||||
} |
|
||||||
GPR_ASSERT(sd->connectivity_notification_pending); |
|
||||||
sd->connectivity_notification_pending = false; |
|
||||||
} |
|
||||||
|
|
||||||
grpc_lb_subchannel_list* grpc_lb_subchannel_list_create( |
|
||||||
grpc_core::LoadBalancingPolicy* p, grpc_core::TraceFlag* tracer, |
|
||||||
const grpc_lb_addresses* addresses, grpc_combiner* combiner, |
|
||||||
grpc_client_channel_factory* client_channel_factory, |
|
||||||
const grpc_channel_args& args, grpc_iomgr_cb_func connectivity_changed_cb) { |
|
||||||
grpc_lb_subchannel_list* subchannel_list = |
|
||||||
static_cast<grpc_lb_subchannel_list*>( |
|
||||||
gpr_zalloc(sizeof(*subchannel_list))); |
|
||||||
if (tracer->enabled()) { |
|
||||||
gpr_log(GPR_DEBUG, |
|
||||||
"[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", |
|
||||||
tracer->name(), p, subchannel_list, addresses->num_addresses); |
|
||||||
} |
|
||||||
subchannel_list->policy = p; |
|
||||||
subchannel_list->tracer = tracer; |
|
||||||
gpr_ref_init(&subchannel_list->refcount, 1); |
|
||||||
subchannel_list->subchannels = static_cast<grpc_lb_subchannel_data*>( |
|
||||||
gpr_zalloc(sizeof(grpc_lb_subchannel_data) * addresses->num_addresses)); |
|
||||||
// We need to remove the LB addresses in order to be able to compare the
|
|
||||||
// subchannel keys of subchannels from a different batch of addresses.
|
|
||||||
static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, |
|
||||||
GRPC_ARG_LB_ADDRESSES}; |
|
||||||
// Create a subchannel for each address.
|
|
||||||
grpc_subchannel_args sc_args; |
|
||||||
size_t subchannel_index = 0; |
|
||||||
for (size_t i = 0; i < addresses->num_addresses; i++) { |
|
||||||
// If there were any balancer, we would have chosen grpclb policy instead.
|
|
||||||
GPR_ASSERT(!addresses->addresses[i].is_balancer); |
|
||||||
memset(&sc_args, 0, sizeof(grpc_subchannel_args)); |
|
||||||
grpc_arg addr_arg = |
|
||||||
grpc_create_subchannel_address_arg(&addresses->addresses[i].address); |
|
||||||
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( |
|
||||||
&args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1); |
|
||||||
gpr_free(addr_arg.value.string); |
|
||||||
sc_args.args = new_args; |
|
||||||
grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( |
|
||||||
client_channel_factory, &sc_args); |
|
||||||
grpc_channel_args_destroy(new_args); |
|
||||||
if (subchannel == nullptr) { |
|
||||||
// Subchannel could not be created.
|
|
||||||
if (tracer->enabled()) { |
|
||||||
char* address_uri = |
|
||||||
grpc_sockaddr_to_uri(&addresses->addresses[i].address); |
|
||||||
gpr_log(GPR_DEBUG, |
|
||||||
"[%s %p] could not create subchannel for address uri %s, " |
|
||||||
"ignoring", |
|
||||||
tracer->name(), subchannel_list->policy, address_uri); |
|
||||||
gpr_free(address_uri); |
|
||||||
} |
|
||||||
continue; |
|
||||||
} |
|
||||||
if (tracer->enabled()) { |
|
||||||
char* address_uri = |
|
||||||
grpc_sockaddr_to_uri(&addresses->addresses[i].address); |
|
||||||
gpr_log(GPR_DEBUG, |
|
||||||
"[%s %p] subchannel list %p index %" PRIuPTR |
|
||||||
": Created subchannel %p for address uri %s", |
|
||||||
tracer->name(), p, subchannel_list, subchannel_index, subchannel, |
|
||||||
address_uri); |
|
||||||
gpr_free(address_uri); |
|
||||||
} |
|
||||||
grpc_lb_subchannel_data* sd = |
|
||||||
&subchannel_list->subchannels[subchannel_index++]; |
|
||||||
sd->subchannel_list = subchannel_list; |
|
||||||
sd->subchannel = subchannel; |
|
||||||
GRPC_CLOSURE_INIT(&sd->connectivity_changed_closure, |
|
||||||
connectivity_changed_cb, sd, |
|
||||||
grpc_combiner_scheduler(combiner)); |
|
||||||
// We assume that the current state is IDLE. If not, we'll get a
|
|
||||||
// callback telling us that.
|
|
||||||
sd->prev_connectivity_state = GRPC_CHANNEL_IDLE; |
|
||||||
sd->curr_connectivity_state = GRPC_CHANNEL_IDLE; |
|
||||||
sd->pending_connectivity_state_unsafe = GRPC_CHANNEL_IDLE; |
|
||||||
sd->user_data_vtable = addresses->user_data_vtable; |
|
||||||
if (sd->user_data_vtable != nullptr) { |
|
||||||
sd->user_data = |
|
||||||
sd->user_data_vtable->copy(addresses->addresses[i].user_data); |
|
||||||
} |
|
||||||
} |
|
||||||
subchannel_list->num_subchannels = subchannel_index; |
|
||||||
subchannel_list->num_idle = subchannel_index; |
|
||||||
return subchannel_list; |
|
||||||
} |
|
||||||
|
|
||||||
static void subchannel_list_destroy(grpc_lb_subchannel_list* subchannel_list) { |
|
||||||
if (subchannel_list->tracer->enabled()) { |
|
||||||
gpr_log(GPR_DEBUG, "[%s %p] Destroying subchannel_list %p", |
|
||||||
subchannel_list->tracer->name(), subchannel_list->policy, |
|
||||||
subchannel_list); |
|
||||||
} |
|
||||||
for (size_t i = 0; i < subchannel_list->num_subchannels; i++) { |
|
||||||
grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i]; |
|
||||||
grpc_lb_subchannel_data_unref_subchannel(sd, "subchannel_list_destroy"); |
|
||||||
} |
|
||||||
gpr_free(subchannel_list->subchannels); |
|
||||||
gpr_free(subchannel_list); |
|
||||||
} |
|
||||||
|
|
||||||
void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list, |
|
||||||
const char* reason) { |
|
||||||
gpr_ref_non_zero(&subchannel_list->refcount); |
|
||||||
if (subchannel_list->tracer->enabled()) { |
|
||||||
const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count); |
|
||||||
gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p REF %lu->%lu (%s)", |
|
||||||
subchannel_list->tracer->name(), subchannel_list->policy, |
|
||||||
subchannel_list, static_cast<unsigned long>(count - 1), |
|
||||||
static_cast<unsigned long>(count), reason); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list, |
|
||||||
const char* reason) { |
|
||||||
const bool done = gpr_unref(&subchannel_list->refcount); |
|
||||||
if (subchannel_list->tracer->enabled()) { |
|
||||||
const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count); |
|
||||||
gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p UNREF %lu->%lu (%s)", |
|
||||||
subchannel_list->tracer->name(), subchannel_list->policy, |
|
||||||
subchannel_list, static_cast<unsigned long>(count + 1), |
|
||||||
static_cast<unsigned long>(count), reason); |
|
||||||
} |
|
||||||
if (done) { |
|
||||||
subchannel_list_destroy(subchannel_list); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void subchannel_data_cancel_connectivity_watch( |
|
||||||
grpc_lb_subchannel_data* sd, const char* reason) { |
|
||||||
if (sd->subchannel_list->tracer->enabled()) { |
|
||||||
gpr_log(GPR_DEBUG, |
|
||||||
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR |
|
||||||
" (subchannel %p): canceling connectivity watch (%s)", |
|
||||||
sd->subchannel_list->tracer->name(), sd->subchannel_list->policy, |
|
||||||
sd->subchannel_list, |
|
||||||
static_cast<size_t>(sd - sd->subchannel_list->subchannels), |
|
||||||
sd->subchannel_list->num_subchannels, sd->subchannel, reason); |
|
||||||
} |
|
||||||
grpc_subchannel_notify_on_state_change(sd->subchannel, nullptr, nullptr, |
|
||||||
&sd->connectivity_changed_closure); |
|
||||||
} |
|
||||||
|
|
||||||
void grpc_lb_subchannel_list_shutdown_and_unref( |
|
||||||
grpc_lb_subchannel_list* subchannel_list, const char* reason) { |
|
||||||
if (subchannel_list->tracer->enabled()) { |
|
||||||
gpr_log(GPR_DEBUG, "[%s %p] Shutting down subchannel_list %p (%s)", |
|
||||||
subchannel_list->tracer->name(), subchannel_list->policy, |
|
||||||
subchannel_list, reason); |
|
||||||
} |
|
||||||
GPR_ASSERT(!subchannel_list->shutting_down); |
|
||||||
subchannel_list->shutting_down = true; |
|
||||||
for (size_t i = 0; i < subchannel_list->num_subchannels; i++) { |
|
||||||
grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i]; |
|
||||||
// If there's a pending notification for this subchannel, cancel it;
|
|
||||||
// the callback is responsible for unreffing the subchannel.
|
|
||||||
// Otherwise, unref the subchannel directly.
|
|
||||||
if (sd->connectivity_notification_pending) { |
|
||||||
subchannel_data_cancel_connectivity_watch(sd, reason); |
|
||||||
} else if (sd->subchannel != nullptr) { |
|
||||||
grpc_lb_subchannel_data_unref_subchannel(sd, reason); |
|
||||||
} |
|
||||||
} |
|
||||||
grpc_lb_subchannel_list_unref(subchannel_list, reason); |
|
||||||
} |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue