aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/client_config
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/client_config')
-rw-r--r--src/core/lib/client_config/client_config.c2
-rw-r--r--src/core/lib/client_config/client_config.h2
-rw-r--r--src/core/lib/client_config/connector.c2
-rw-r--r--src/core/lib/client_config/connector.h2
-rw-r--r--src/core/lib/client_config/default_initial_connect_string.c2
-rw-r--r--src/core/lib/client_config/initial_connect_string.c2
-rw-r--r--src/core/lib/client_config/initial_connect_string.h2
-rw-r--r--src/core/lib/client_config/lb_policies/load_balancer_api.c163
-rw-r--r--src/core/lib/client_config/lb_policies/load_balancer_api.h85
-rw-r--r--src/core/lib/client_config/lb_policies/pick_first.c421
-rw-r--r--src/core/lib/client_config/lb_policies/pick_first.h43
-rw-r--r--src/core/lib/client_config/lb_policies/round_robin.c542
-rw-r--r--src/core/lib/client_config/lb_policies/round_robin.h46
-rw-r--r--src/core/lib/client_config/lb_policy.c2
-rw-r--r--src/core/lib/client_config/lb_policy.h2
-rw-r--r--src/core/lib/client_config/lb_policy_factory.c7
-rw-r--r--src/core/lib/client_config/lb_policy_factory.h17
-rw-r--r--src/core/lib/client_config/lb_policy_registry.c13
-rw-r--r--src/core/lib/client_config/lb_policy_registry.h7
-rw-r--r--src/core/lib/client_config/resolver.c2
-rw-r--r--src/core/lib/client_config/resolver.h2
-rw-r--r--src/core/lib/client_config/resolver_factory.c2
-rw-r--r--src/core/lib/client_config/resolver_factory.h2
-rw-r--r--src/core/lib/client_config/resolver_registry.c24
-rw-r--r--src/core/lib/client_config/resolver_registry.h6
-rw-r--r--src/core/lib/client_config/resolvers/dns_resolver.c309
-rw-r--r--src/core/lib/client_config/resolvers/dns_resolver.h42
-rw-r--r--src/core/lib/client_config/resolvers/sockaddr_resolver.c372
-rw-r--r--src/core/lib/client_config/resolvers/sockaddr_resolver.h50
-rw-r--r--src/core/lib/client_config/resolvers/zookeeper_resolver.c520
-rw-r--r--src/core/lib/client_config/resolvers/zookeeper_resolver.h42
-rw-r--r--src/core/lib/client_config/subchannel.c2
-rw-r--r--src/core/lib/client_config/subchannel.h2
-rw-r--r--src/core/lib/client_config/subchannel_factory.c2
-rw-r--r--src/core/lib/client_config/subchannel_factory.h2
-rw-r--r--src/core/lib/client_config/uri_parser.c70
-rw-r--r--src/core/lib/client_config/uri_parser.h14
37 files changed, 143 insertions, 2684 deletions
diff --git a/src/core/lib/client_config/client_config.c b/src/core/lib/client_config/client_config.c
index 82c8d68099..2521023364 100644
--- a/src/core/lib/client_config/client_config.c
+++ b/src/core/lib/client_config/client_config.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/client_config.h b/src/core/lib/client_config/client_config.h
index 404ec0d3a5..8dc2f6b299 100644
--- a/src/core/lib/client_config/client_config.h
+++ b/src/core/lib/client_config/client_config.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/connector.c b/src/core/lib/client_config/connector.c
index f51d862c6d..4c7b823dac 100644
--- a/src/core/lib/client_config/connector.c
+++ b/src/core/lib/client_config/connector.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/connector.h b/src/core/lib/client_config/connector.h
index 21b925aade..39870a261c 100644
--- a/src/core/lib/client_config/connector.h
+++ b/src/core/lib/client_config/connector.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/default_initial_connect_string.c b/src/core/lib/client_config/default_initial_connect_string.c
index 86eb37de77..a70da4a84a 100644
--- a/src/core/lib/client_config/default_initial_connect_string.c
+++ b/src/core/lib/client_config/default_initial_connect_string.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/initial_connect_string.c b/src/core/lib/client_config/initial_connect_string.c
index 95ae728316..4034ea2e87 100644
--- a/src/core/lib/client_config/initial_connect_string.c
+++ b/src/core/lib/client_config/initial_connect_string.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/initial_connect_string.h b/src/core/lib/client_config/initial_connect_string.h
index eec42fa240..51302768c6 100644
--- a/src/core/lib/client_config/initial_connect_string.h
+++ b/src/core/lib/client_config/initial_connect_string.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/lb_policies/load_balancer_api.c b/src/core/lib/client_config/lb_policies/load_balancer_api.c
deleted file mode 100644
index 4cbed200df..0000000000
--- a/src/core/lib/client_config/lb_policies/load_balancer_api.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- *
- * Copyright 2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/client_config/lb_policies/load_balancer_api.h"
-#include "third_party/nanopb/pb_decode.h"
-#include "third_party/nanopb/pb_encode.h"
-
-#include <grpc/support/alloc.h>
-
-typedef struct decode_serverlist_arg {
- int first_pass;
- int i;
- size_t num_servers;
- grpc_grpclb_server **servers;
-} decode_serverlist_arg;
-
-/* invoked once for every Server in ServerList */
-static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
- void **arg) {
- decode_serverlist_arg *dec_arg = *arg;
- if (dec_arg->first_pass != 0) { /* first pass */
- grpc_grpclb_server server;
- if (!pb_decode(stream, grpc_lb_v0_Server_fields, &server)) {
- return false;
- }
- dec_arg->num_servers++;
- } else { /* second pass */
- grpc_grpclb_server *server = gpr_malloc(sizeof(grpc_grpclb_server));
- GPR_ASSERT(dec_arg->num_servers > 0);
- if (dec_arg->i == 0) { /* first iteration of second pass */
- dec_arg->servers =
- gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers);
- }
- if (!pb_decode(stream, grpc_lb_v0_Server_fields, server)) {
- return false;
- }
- dec_arg->servers[dec_arg->i++] = server;
- }
-
- return true;
-}
-
-grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name) {
- grpc_grpclb_request *req = gpr_malloc(sizeof(grpc_grpclb_request));
-
- req->has_client_stats = 0; /* TODO(dgq): add support for stats once defined */
- req->has_initial_request = 1;
- req->initial_request.has_name = 1;
- strncpy(req->initial_request.name, lb_service_name,
- GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH);
- return req;
-}
-
-gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) {
- size_t encoded_length;
- pb_ostream_t sizestream;
- pb_ostream_t outputstream;
- gpr_slice slice;
- memset(&sizestream, 0, sizeof(pb_ostream_t));
- pb_encode(&sizestream, grpc_lb_v0_LoadBalanceRequest_fields, request);
- encoded_length = sizestream.bytes_written;
-
- slice = gpr_slice_malloc(encoded_length);
- outputstream =
- pb_ostream_from_buffer(GPR_SLICE_START_PTR(slice), encoded_length);
- GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v0_LoadBalanceRequest_fields,
- request) != 0);
- return slice;
-}
-
-void grpc_grpclb_request_destroy(grpc_grpclb_request *request) {
- gpr_free(request);
-}
-
-grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) {
- bool status;
- pb_istream_t stream =
- pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
- GPR_SLICE_LENGTH(encoded_response));
- grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
- memset(res, 0, sizeof(*res));
- status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
- GPR_ASSERT(status == true);
- return res;
-}
-
-grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
- gpr_slice encoded_response) {
- grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist));
- bool status;
- decode_serverlist_arg arg;
- pb_istream_t stream =
- pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
- GPR_SLICE_LENGTH(encoded_response));
- pb_istream_t stream_at_start = stream;
- grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
- memset(res, 0, sizeof(*res));
- memset(&arg, 0, sizeof(decode_serverlist_arg));
-
- res->server_list.servers.funcs.decode = decode_serverlist;
- res->server_list.servers.arg = &arg;
- arg.first_pass = 1;
- status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
- GPR_ASSERT(status == true);
- GPR_ASSERT(arg.num_servers > 0);
-
- arg.first_pass = 0;
- status =
- pb_decode(&stream_at_start, grpc_lb_v0_LoadBalanceResponse_fields, res);
- GPR_ASSERT(status == true);
- GPR_ASSERT(arg.servers != NULL);
-
- sl->num_servers = arg.num_servers;
- sl->servers = arg.servers;
- if (res->server_list.has_expiration_interval) {
- sl->expiration_interval = res->server_list.expiration_interval;
- }
- grpc_grpclb_response_destroy(res);
- return sl;
-}
-
-void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) {
- size_t i;
- for (i = 0; i < serverlist->num_servers; i++) {
- gpr_free(serverlist->servers[i]);
- }
- gpr_free(serverlist->servers);
- gpr_free(serverlist);
-}
-
-void grpc_grpclb_response_destroy(grpc_grpclb_response *response) {
- gpr_free(response);
-}
diff --git a/src/core/lib/client_config/lb_policies/load_balancer_api.h b/src/core/lib/client_config/lb_policies/load_balancer_api.h
deleted file mode 100644
index 83299adfa9..0000000000
--- a/src/core/lib/client_config/lb_policies/load_balancer_api.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- * Copyright 2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
-#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
-
-#include <grpc/support/slice_buffer.h>
-
-#include "src/core/lib/client_config/lb_policy_factory.h"
-#include "src/core/lib/proto/grpc/lb/v0/load_balancer.pb.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
-
-typedef grpc_lb_v0_LoadBalanceRequest grpc_grpclb_request;
-typedef grpc_lb_v0_LoadBalanceResponse grpc_grpclb_response;
-typedef grpc_lb_v0_Server grpc_grpclb_server;
-typedef grpc_lb_v0_Duration grpc_grpclb_duration;
-typedef struct grpc_grpclb_serverlist {
- grpc_grpclb_server **servers;
- size_t num_servers;
- grpc_grpclb_duration expiration_interval;
-} grpc_grpclb_serverlist;
-
-/** Create a request for a gRPC LB service under \a lb_service_name */
-grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name);
-
-/** Protocol Buffers v3-encode \a request */
-gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request);
-
-/** Destroy \a request */
-void grpc_grpclb_request_destroy(grpc_grpclb_request *request);
-
-/** Parse (ie, decode) the bytes in \a encoded_response as a \a
- * grpc_grpclb_response */
-grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response);
-
-/** Destroy \a serverlist */
-void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist);
-
-/** Parse the list of servers from an encoded \a grpc_grpclb_response */
-grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
- gpr_slice encoded_response);
-
-/** Destroy \a response */
-void grpc_grpclb_response_destroy(grpc_grpclb_response *response);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */
diff --git a/src/core/lib/client_config/lb_policies/pick_first.c b/src/core/lib/client_config/lb_policies/pick_first.c
deleted file mode 100644
index 2e399b73f9..0000000000
--- a/src/core/lib/client_config/lb_policies/pick_first.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/client_config/lb_policies/pick_first.h"
-#include "src/core/lib/client_config/lb_policy_factory.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include "src/core/lib/transport/connectivity_state.h"
-
-typedef struct pending_pick {
- struct pending_pick *next;
- grpc_pollset *pollset;
- grpc_connected_subchannel **target;
- grpc_closure *on_complete;
-} pending_pick;
-
-typedef struct {
- /** base policy: must be first */
- grpc_lb_policy base;
- /** all our subchannels */
- grpc_subchannel **subchannels;
- size_t num_subchannels;
-
- grpc_closure connectivity_changed;
-
- /** the selected channel (a grpc_connected_subchannel) */
- gpr_atm selected;
-
- /** mutex protecting remaining members */
- gpr_mu mu;
- /** have we started picking? */
- int started_picking;
- /** are we shut down? */
- int shutdown;
- /** which subchannel are we watching? */
- size_t checking_subchannel;
- /** what is the connectivity of that channel? */
- grpc_connectivity_state checking_connectivity;
- /** list of picks that are waiting on connectivity */
- pending_pick *pending_picks;
-
- /** our connectivity state tracker */
- grpc_connectivity_state_tracker state_tracker;
-} pick_first_lb_policy;
-
-#define GET_SELECTED(p) \
- ((grpc_connected_subchannel *)gpr_atm_acq_load(&(p)->selected))
-
-void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- grpc_connected_subchannel *selected = GET_SELECTED(p);
- size_t i;
- GPR_ASSERT(p->pending_picks == NULL);
- for (i = 0; i < p->num_subchannels; i++) {
- GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i], "pick_first");
- }
- if (selected != NULL) {
- GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, selected, "picked_first");
- }
- grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker);
- gpr_free(p->subchannels);
- gpr_mu_destroy(&p->mu);
- gpr_free(p);
-}
-
-void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- pending_pick *pp;
- grpc_connected_subchannel *selected;
- gpr_mu_lock(&p->mu);
- selected = GET_SELECTED(p);
- p->shutdown = 1;
- pp = p->pending_picks;
- p->pending_picks = NULL;
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_FATAL_FAILURE, "shutdown");
- /* cancel subscription */
- if (selected != NULL) {
- grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, selected, NULL, NULL, &p->connectivity_changed);
- } else {
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL,
- &p->connectivity_changed);
- }
- gpr_mu_unlock(&p->mu);
- while (pp != NULL) {
- pending_pick *next = pp->next;
- *pp->target = NULL;
- grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
- pp->pollset);
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
- gpr_free(pp);
- pp = next;
- }
-}
-
-static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
- grpc_connected_subchannel **target) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- pending_pick *pp;
- gpr_mu_lock(&p->mu);
- pp = p->pending_picks;
- p->pending_picks = NULL;
- while (pp != NULL) {
- pending_pick *next = pp->next;
- if (pp->target == target) {
- grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
- pp->pollset);
- *target = NULL;
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
- gpr_free(pp);
- } else {
- pp->next = p->pending_picks;
- p->pending_picks = pp;
- }
- pp = next;
- }
- gpr_mu_unlock(&p->mu);
-}
-
-static void start_picking(grpc_exec_ctx *exec_ctx, pick_first_lb_policy *p) {
- p->started_picking = 1;
- p->checking_subchannel = 0;
- p->checking_connectivity = GRPC_CHANNEL_IDLE;
- GRPC_LB_POLICY_WEAK_REF(&p->base, "pick_first_connectivity");
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
-}
-
-void pf_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- gpr_mu_lock(&p->mu);
- if (!p->started_picking) {
- start_picking(exec_ctx, p);
- }
- gpr_mu_unlock(&p->mu);
-}
-
-int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset,
- grpc_metadata_batch *initial_metadata,
- grpc_connected_subchannel **target, grpc_closure *on_complete) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- pending_pick *pp;
-
- /* Check atomically for a selected channel */
- grpc_connected_subchannel *selected = GET_SELECTED(p);
- if (selected != NULL) {
- *target = selected;
- return 1;
- }
-
- /* No subchannel selected yet, so acquire lock and then attempt again */
- gpr_mu_lock(&p->mu);
- selected = GET_SELECTED(p);
- if (selected) {
- gpr_mu_unlock(&p->mu);
- *target = selected;
- return 1;
- } else {
- if (!p->started_picking) {
- start_picking(exec_ctx, p);
- }
- grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
- pp = gpr_malloc(sizeof(*pp));
- pp->next = p->pending_picks;
- pp->pollset = pollset;
- pp->target = target;
- pp->on_complete = on_complete;
- p->pending_picks = pp;
- gpr_mu_unlock(&p->mu);
- return 0;
- }
-}
-
-static void destroy_subchannels(grpc_exec_ctx *exec_ctx, void *arg,
- bool iomgr_success) {
- pick_first_lb_policy *p = arg;
- size_t i;
- size_t num_subchannels = p->num_subchannels;
- grpc_subchannel **subchannels;
-
- gpr_mu_lock(&p->mu);
- subchannels = p->subchannels;
- p->num_subchannels = 0;
- p->subchannels = NULL;
- gpr_mu_unlock(&p->mu);
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "destroy_subchannels");
-
- for (i = 0; i < num_subchannels; i++) {
- GRPC_SUBCHANNEL_UNREF(exec_ctx, subchannels[i], "pick_first");
- }
-
- gpr_free(subchannels);
-}
-
-static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
- bool iomgr_success) {
- pick_first_lb_policy *p = arg;
- grpc_subchannel *selected_subchannel;
- pending_pick *pp;
- grpc_connected_subchannel *selected;
-
- gpr_mu_lock(&p->mu);
-
- selected = GET_SELECTED(p);
-
- if (p->shutdown) {
- gpr_mu_unlock(&p->mu);
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity");
- return;
- } else if (selected != NULL) {
- if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- /* if the selected channel goes bad, we're done */
- p->checking_connectivity = GRPC_CHANNEL_FATAL_FAILURE;
- }
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- p->checking_connectivity, "selected_changed");
- if (p->checking_connectivity != GRPC_CHANNEL_FATAL_FAILURE) {
- grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, selected, p->base.interested_parties,
- &p->checking_connectivity, &p->connectivity_changed);
- } else {
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity");
- }
- } else {
- loop:
- switch (p->checking_connectivity) {
- case GRPC_CHANNEL_READY:
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_READY, "connecting_ready");
- selected_subchannel = p->subchannels[p->checking_subchannel];
- selected =
- grpc_subchannel_get_connected_subchannel(selected_subchannel);
- GPR_ASSERT(selected != NULL);
- GRPC_CONNECTED_SUBCHANNEL_REF(selected, "picked_first");
- /* drop the pick list: we are connected now */
- GRPC_LB_POLICY_WEAK_REF(&p->base, "destroy_subchannels");
- gpr_atm_rel_store(&p->selected, (gpr_atm)selected);
- grpc_exec_ctx_enqueue(
- exec_ctx, grpc_closure_create(destroy_subchannels, p), true, NULL);
- /* update any calls that were waiting for a pick */
- while ((pp = p->pending_picks)) {
- p->pending_picks = pp->next;
- *pp->target = selected;
- grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
- pp->pollset);
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
- gpr_free(pp);
- }
- grpc_connected_subchannel_notify_on_state_change(
- exec_ctx, selected, p->base.interested_parties,
- &p->checking_connectivity, &p->connectivity_changed);
- break;
- case GRPC_CHANNEL_TRANSIENT_FAILURE:
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_TRANSIENT_FAILURE,
- "connecting_transient_failure");
- p->checking_subchannel =
- (p->checking_subchannel + 1) % p->num_subchannels;
- p->checking_connectivity = grpc_subchannel_check_connectivity(
- p->subchannels[p->checking_subchannel]);
- if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
- } else {
- goto loop;
- }
- break;
- case GRPC_CHANNEL_CONNECTING:
- case GRPC_CHANNEL_IDLE:
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_CONNECTING,
- "connecting_changed");
- grpc_subchannel_notify_on_state_change(
- exec_ctx, p->subchannels[p->checking_subchannel],
- p->base.interested_parties, &p->checking_connectivity,
- &p->connectivity_changed);
- break;
- case GRPC_CHANNEL_FATAL_FAILURE:
- p->num_subchannels--;
- GPR_SWAP(grpc_subchannel *, p->subchannels[p->checking_subchannel],
- p->subchannels[p->num_subchannels]);
- GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[p->num_subchannels],
- "pick_first");
- if (p->num_subchannels == 0) {
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_FATAL_FAILURE,
- "no_more_channels");
- while ((pp = p->pending_picks)) {
- p->pending_picks = pp->next;
- *pp->target = NULL;
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
- gpr_free(pp);
- }
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base,
- "pick_first_connectivity");
- } else {
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_TRANSIENT_FAILURE,
- "subchannel_failed");
- p->checking_subchannel %= p->num_subchannels;
- p->checking_connectivity = grpc_subchannel_check_connectivity(
- p->subchannels[p->checking_subchannel]);
- goto loop;
- }
- }
- }
-
- gpr_mu_unlock(&p->mu);
-}
-
-static grpc_connectivity_state pf_check_connectivity(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *pol) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- grpc_connectivity_state st;
- gpr_mu_lock(&p->mu);
- st = grpc_connectivity_state_check(&p->state_tracker);
- gpr_mu_unlock(&p->mu);
- return st;
-}
-
-void pf_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
- grpc_connectivity_state *current,
- grpc_closure *notify) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- gpr_mu_lock(&p->mu);
- grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker,
- current, notify);
- gpr_mu_unlock(&p->mu);
-}
-
-void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
- grpc_closure *closure) {
- pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
- grpc_connected_subchannel *selected = GET_SELECTED(p);
- if (selected) {
- grpc_connected_subchannel_ping(exec_ctx, selected, closure);
- } else {
- grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL);
- }
-}
-
-static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = {
- pf_destroy,
- pf_shutdown,
- pf_pick,
- pf_cancel_pick,
- pf_ping_one,
- pf_exit_idle,
- pf_check_connectivity,
- pf_notify_on_state_change};
-
-static void pick_first_factory_ref(grpc_lb_policy_factory *factory) {}
-
-static void pick_first_factory_unref(grpc_lb_policy_factory *factory) {}
-
-static grpc_lb_policy *create_pick_first(grpc_lb_policy_factory *factory,
- grpc_lb_policy_args *args) {
- if (args->num_subchannels == 0) return NULL;
- pick_first_lb_policy *p = gpr_malloc(sizeof(*p));
- memset(p, 0, sizeof(*p));
- grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable);
- p->subchannels =
- gpr_malloc(sizeof(grpc_subchannel *) * args->num_subchannels);
- p->num_subchannels = args->num_subchannels;
- grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE,
- "pick_first");
- memcpy(p->subchannels, args->subchannels,
- sizeof(grpc_subchannel *) * args->num_subchannels);
- grpc_closure_init(&p->connectivity_changed, pf_connectivity_changed, p);
- gpr_mu_init(&p->mu);
- return &p->base;
-}
-
-static const grpc_lb_policy_factory_vtable pick_first_factory_vtable = {
- pick_first_factory_ref, pick_first_factory_unref, create_pick_first,
- "pick_first"};
-
-static grpc_lb_policy_factory pick_first_lb_policy_factory = {
- &pick_first_factory_vtable};
-
-grpc_lb_policy_factory *grpc_pick_first_lb_factory_create() {
- return &pick_first_lb_policy_factory;
-}
diff --git a/src/core/lib/client_config/lb_policies/pick_first.h b/src/core/lib/client_config/lb_policies/pick_first.h
deleted file mode 100644
index dba86ea7ad..0000000000
--- a/src/core/lib/client_config/lb_policies/pick_first.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H
-#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H
-
-#include "src/core/lib/client_config/lb_policy_factory.h"
-
-/** Returns a load balancing factory for the pick first policy, which picks up
- * the first subchannel from \a subchannels to succesfully connect */
-grpc_lb_policy_factory *grpc_pick_first_lb_factory_create();
-
-#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H */
diff --git a/src/core/lib/client_config/lb_policies/round_robin.c b/src/core/lib/client_config/lb_policies/round_robin.c
deleted file mode 100644
index c904c5f921..0000000000
--- a/src/core/lib/client_config/lb_policies/round_robin.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/client_config/lb_policies/round_robin.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include "src/core/lib/transport/connectivity_state.h"
-
-typedef struct round_robin_lb_policy round_robin_lb_policy;
-
-int grpc_lb_round_robin_trace = 0;
-
-/** List of entities waiting for a pick.
- *
- * Once a pick is available, \a target is updated and \a on_complete called. */
-typedef struct pending_pick {
- struct pending_pick *next;
- grpc_pollset *pollset;
- grpc_connected_subchannel **target;
- grpc_closure *on_complete;
-} pending_pick;
-
-/** List of subchannels in a connectivity READY state */
-typedef struct ready_list {
- grpc_subchannel *subchannel;
- struct ready_list *next;
- struct ready_list *prev;
-} ready_list;
-
-typedef struct {
- /** index within policy->subchannels */
- size_t index;
- /** backpointer to owning policy */
- round_robin_lb_policy *policy;
- /** subchannel itself */
- grpc_subchannel *subchannel;
- /** notification that connectivity has changed on subchannel */
- grpc_closure connectivity_changed_closure;
- /** this subchannels current position in subchannel->ready_list */
- ready_list *ready_list_node;
- /** last observed connectivity */
- grpc_connectivity_state connectivity_state;
-} subchannel_data;
-
-struct round_robin_lb_policy {
- /** base policy: must be first */
- grpc_lb_policy base;
-
- /** all our subchannels */
- size_t num_subchannels;
- subchannel_data **subchannels;
-
- /** mutex protecting remaining members */
- gpr_mu mu;
- /** have we started picking? */
- int started_picking;
- /** are we shutting down? */
- int shutdown;
- /** List of picks that are waiting on connectivity */
- pending_pick *pending_picks;
-
- /** our connectivity state tracker */
- grpc_connectivity_state_tracker state_tracker;
-
- /** (Dummy) root of the doubly linked list containing READY subchannels */
- ready_list ready_list;
- /** Last pick from the ready list. */
- ready_list *ready_list_last_pick;
-};
-
-/** Returns the next subchannel from the connected list or NULL if the list is
- * empty.
- *
- * Note that this function does *not* advance p->ready_list_last_pick. Use \a
- * advance_last_picked_locked() for that. */
-static ready_list *peek_next_connected_locked(const round_robin_lb_policy *p) {
- ready_list *selected;
- selected = p->ready_list_last_pick->next;
-
- while (selected != NULL) {
- if (selected == &p->ready_list) {
- GPR_ASSERT(selected->subchannel == NULL);
- /* skip dummy root */
- selected = selected->next;
- } else {
- GPR_ASSERT(selected->subchannel != NULL);
- return selected;
- }
- }
- return NULL;
-}
-
-/** Advance the \a ready_list picking head. */
-static void advance_last_picked_locked(round_robin_lb_policy *p) {
- if (p->ready_list_last_pick->next != NULL) { /* non-empty list */
- p->ready_list_last_pick = p->ready_list_last_pick->next;
- if (p->ready_list_last_pick == &p->ready_list) {
- /* skip dummy root */
- p->ready_list_last_pick = p->ready_list_last_pick->next;
- }
- } else { /* should be an empty list */
- GPR_ASSERT(p->ready_list_last_pick == &p->ready_list);
- }
-
- if (grpc_lb_round_robin_trace) {
- gpr_log(GPR_DEBUG, "[READYLIST] ADVANCED LAST PICK. NOW AT NODE %p (SC %p)",
- p->ready_list_last_pick, p->ready_list_last_pick->subchannel);
- }
-}
-
-/** Prepends (relative to the root at p->ready_list) the connected subchannel \a
- * csc to the list of ready subchannels. */
-static ready_list *add_connected_sc_locked(round_robin_lb_policy *p,
- grpc_subchannel *sc) {
- ready_list *new_elem = gpr_malloc(sizeof(ready_list));
- new_elem->subchannel = sc;
- if (p->ready_list.prev == NULL) {
- /* first element */
- new_elem->next = &p->ready_list;
- new_elem->prev = &p->ready_list;
- p->ready_list.next = new_elem;
- p->ready_list.prev = new_elem;
- } else {
- new_elem->next = &p->ready_list;
- new_elem->prev = p->ready_list.prev;
- p->ready_list.prev->next = new_elem;
- p->ready_list.prev = new_elem;
- }
- if (grpc_lb_round_robin_trace) {
- gpr_log(GPR_DEBUG, "[READYLIST] ADDING NODE %p (SC %p)", new_elem, sc);
- }
- return new_elem;
-}
-
-/** Removes \a node from the list of connected subchannels */
-static void remove_disconnected_sc_locked(round_robin_lb_policy *p,
- ready_list *node) {
- if (node == NULL) {
- return;
- }
- if (node == p->ready_list_last_pick) {
- /* If removing the lastly picked node, reset the last pick pointer to the
- * dummy root of the list */
- p->ready_list_last_pick = &p->ready_list;
- }
-
- /* removing last item */
- if (node->next == &p->ready_list && node->prev == &p->ready_list) {
- GPR_ASSERT(p->ready_list.next == node);
- GPR_ASSERT(p->ready_list.prev == node);
- p->ready_list.next = NULL;
- p->ready_list.prev = NULL;
- } else {
- node->prev->next = node->next;
- node->next->prev = node->prev;
- }
-
- if (grpc_lb_round_robin_trace) {
- gpr_log(GPR_DEBUG, "[READYLIST] REMOVED NODE %p (SC %p)", node,
- node->subchannel);
- }
-
- node->next = NULL;
- node->prev = NULL;
- node->subchannel = NULL;
-
- gpr_free(node);
-}
-
-void rr_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- size_t i;
- ready_list *elem;
- for (i = 0; i < p->num_subchannels; i++) {
- subchannel_data *sd = p->subchannels[i];
- GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin");
- gpr_free(sd);
- }
-
- grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker);
- gpr_free(p->subchannels);
- gpr_mu_destroy(&p->mu);
-
- elem = p->ready_list.next;
- while (elem != NULL && elem != &p->ready_list) {
- ready_list *tmp;
- tmp = elem->next;
- elem->next = NULL;
- elem->prev = NULL;
- elem->subchannel = NULL;
- gpr_free(elem);
- elem = tmp;
- }
- gpr_free(p);
-}
-
-void rr_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- pending_pick *pp;
- size_t i;
-
- gpr_mu_lock(&p->mu);
-
- p->shutdown = 1;
- while ((pp = p->pending_picks)) {
- p->pending_picks = pp->next;
- *pp->target = NULL;
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
- gpr_free(pp);
- }
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_FATAL_FAILURE, "shutdown");
- for (i = 0; i < p->num_subchannels; i++) {
- subchannel_data *sd = p->subchannels[i];
- grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL, NULL,
- &sd->connectivity_changed_closure);
- }
- gpr_mu_unlock(&p->mu);
-}
-
-static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
- grpc_connected_subchannel **target) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- pending_pick *pp;
- gpr_mu_lock(&p->mu);
- pp = p->pending_picks;
- p->pending_picks = NULL;
- while (pp != NULL) {
- pending_pick *next = pp->next;
- if (pp->target == target) {
- grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
- pp->pollset);
- *target = NULL;
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
- gpr_free(pp);
- } else {
- pp->next = p->pending_picks;
- p->pending_picks = pp;
- }
- pp = next;
- }
- gpr_mu_unlock(&p->mu);
-}
-
-static void start_picking(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p) {
- size_t i;
- p->started_picking = 1;
-
- gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p,
- p->num_subchannels);
-
- for (i = 0; i < p->num_subchannels; i++) {
- subchannel_data *sd = p->subchannels[i];
- sd->connectivity_state = GRPC_CHANNEL_IDLE;
- grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, p->base.interested_parties,
- &sd->connectivity_state, &sd->connectivity_changed_closure);
- GRPC_LB_POLICY_WEAK_REF(&p->base, "round_robin_connectivity");
- }
-}
-
-void rr_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- gpr_mu_lock(&p->mu);
- if (!p->started_picking) {
- start_picking(exec_ctx, p);
- }
- gpr_mu_unlock(&p->mu);
-}
-
-int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_pollset *pollset,
- grpc_metadata_batch *initial_metadata,
- grpc_connected_subchannel **target, grpc_closure *on_complete) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- pending_pick *pp;
- ready_list *selected;
- gpr_mu_lock(&p->mu);
- if ((selected = peek_next_connected_locked(p))) {
- gpr_mu_unlock(&p->mu);
- *target = grpc_subchannel_get_connected_subchannel(selected->subchannel);
- if (grpc_lb_round_robin_trace) {
- gpr_log(GPR_DEBUG,
- "[RR PICK] TARGET <-- CONNECTED SUBCHANNEL %p (NODE %p)",
- selected->subchannel, selected);
- }
- /* only advance the last picked pointer if the selection was used */
- advance_last_picked_locked(p);
- return 1;
- } else {
- if (!p->started_picking) {
- start_picking(exec_ctx, p);
- }
- grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
- pp = gpr_malloc(sizeof(*pp));
- pp->next = p->pending_picks;
- pp->pollset = pollset;
- pp->target = target;
- pp->on_complete = on_complete;
- p->pending_picks = pp;
- gpr_mu_unlock(&p->mu);
- return 0;
- }
-}
-
-static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
- bool iomgr_success) {
- subchannel_data *sd = arg;
- round_robin_lb_policy *p = sd->policy;
- pending_pick *pp;
- ready_list *selected;
-
- int unref = 0;
-
- gpr_mu_lock(&p->mu);
-
- if (p->shutdown) {
- unref = 1;
- } else {
- switch (sd->connectivity_state) {
- case GRPC_CHANNEL_READY:
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_READY, "connecting_ready");
- /* add the newly connected subchannel to the list of connected ones.
- * Note that it goes to the "end of the line". */
- sd->ready_list_node = add_connected_sc_locked(p, sd->subchannel);
- /* at this point we know there's at least one suitable subchannel. Go
- * ahead and pick one and notify the pending suitors in
- * p->pending_picks. This preemtively replicates rr_pick()'s actions. */
- selected = peek_next_connected_locked(p);
- if (p->pending_picks != NULL) {
- /* if the selected subchannel is going to be used for the pending
- * picks, update the last picked pointer */
- advance_last_picked_locked(p);
- }
- while ((pp = p->pending_picks)) {
- p->pending_picks = pp->next;
- *pp->target =
- grpc_subchannel_get_connected_subchannel(selected->subchannel);
- if (grpc_lb_round_robin_trace) {
- gpr_log(GPR_DEBUG,
- "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
- selected->subchannel, selected);
- }
- grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
- pp->pollset);
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
- gpr_free(pp);
- }
- grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, p->base.interested_parties,
- &sd->connectivity_state, &sd->connectivity_changed_closure);
- break;
- case GRPC_CHANNEL_CONNECTING:
- case GRPC_CHANNEL_IDLE:
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- sd->connectivity_state,
- "connecting_changed");
- grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, p->base.interested_parties,
- &sd->connectivity_state, &sd->connectivity_changed_closure);
- break;
- case GRPC_CHANNEL_TRANSIENT_FAILURE:
- /* renew state notification */
- grpc_subchannel_notify_on_state_change(
- exec_ctx, sd->subchannel, p->base.interested_parties,
- &sd->connectivity_state, &sd->connectivity_changed_closure);
-
- /* remove from ready list if still present */
- if (sd->ready_list_node != NULL) {
- remove_disconnected_sc_locked(p, sd->ready_list_node);
- sd->ready_list_node = NULL;
- }
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_TRANSIENT_FAILURE,
- "connecting_transient_failure");
- break;
- case GRPC_CHANNEL_FATAL_FAILURE:
- if (sd->ready_list_node != NULL) {
- remove_disconnected_sc_locked(p, sd->ready_list_node);
- sd->ready_list_node = NULL;
- }
-
- p->num_subchannels--;
- GPR_SWAP(subchannel_data *, p->subchannels[sd->index],
- p->subchannels[p->num_subchannels]);
- GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin");
- p->subchannels[sd->index]->index = sd->index;
- gpr_free(sd);
-
- unref = 1;
- if (p->num_subchannels == 0) {
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_FATAL_FAILURE,
- "no_more_channels");
- while ((pp = p->pending_picks)) {
- p->pending_picks = pp->next;
- *pp->target = NULL;
- grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
- gpr_free(pp);
- }
- } else {
- grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
- GRPC_CHANNEL_TRANSIENT_FAILURE,
- "subchannel_failed");
- }
- } /* switch */
- } /* !unref */
-
- gpr_mu_unlock(&p->mu);
-
- if (unref) {
- GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "round_robin_connectivity");
- }
-}
-
-static grpc_connectivity_state rr_check_connectivity(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *pol) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- grpc_connectivity_state st;
- gpr_mu_lock(&p->mu);
- st = grpc_connectivity_state_check(&p->state_tracker);
- gpr_mu_unlock(&p->mu);
- return st;
-}
-
-static void rr_notify_on_state_change(grpc_exec_ctx *exec_ctx,
- grpc_lb_policy *pol,
- grpc_connectivity_state *current,
- grpc_closure *notify) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- gpr_mu_lock(&p->mu);
- grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker,
- current, notify);
- gpr_mu_unlock(&p->mu);
-}
-
-static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
- grpc_closure *closure) {
- round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
- ready_list *selected;
- grpc_connected_subchannel *target;
- gpr_mu_lock(&p->mu);
- if ((selected = peek_next_connected_locked(p))) {
- gpr_mu_unlock(&p->mu);
- target = grpc_subchannel_get_connected_subchannel(selected->subchannel);
- grpc_connected_subchannel_ping(exec_ctx, target, closure);
- } else {
- gpr_mu_unlock(&p->mu);
- grpc_exec_ctx_enqueue(exec_ctx, closure, false, NULL);
- }
-}
-
-static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = {
- rr_destroy,
- rr_shutdown,
- rr_pick,
- rr_cancel_pick,
- rr_ping_one,
- rr_exit_idle,
- rr_check_connectivity,
- rr_notify_on_state_change};
-
-static void round_robin_factory_ref(grpc_lb_policy_factory *factory) {}
-
-static void round_robin_factory_unref(grpc_lb_policy_factory *factory) {}
-
-static grpc_lb_policy *create_round_robin(grpc_lb_policy_factory *factory,
- grpc_lb_policy_args *args) {
- size_t i;
- round_robin_lb_policy *p = gpr_malloc(sizeof(*p));
- GPR_ASSERT(args->num_subchannels > 0);
- memset(p, 0, sizeof(*p));
- grpc_lb_policy_init(&p->base, &round_robin_lb_policy_vtable);
- p->num_subchannels = args->num_subchannels;
- p->subchannels = gpr_malloc(sizeof(*p->subchannels) * p->num_subchannels);
- memset(p->subchannels, 0, sizeof(*p->subchannels) * p->num_subchannels);
- grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE,
- "round_robin");
-
- gpr_mu_init(&p->mu);
- for (i = 0; i < args->num_subchannels; i++) {
- subchannel_data *sd = gpr_malloc(sizeof(*sd));
- memset(sd, 0, sizeof(*sd));
- p->subchannels[i] = sd;
- sd->policy = p;
- sd->index = i;
- sd->subchannel = args->subchannels[i];
- grpc_closure_init(&sd->connectivity_changed_closure,
- rr_connectivity_changed, sd);
- }
-
- /* The (dummy node) root of the ready list */
- p->ready_list.subchannel = NULL;
- p->ready_list.prev = NULL;
- p->ready_list.next = NULL;
- p->ready_list_last_pick = &p->ready_list;
-
- return &p->base;
-}
-
-static const grpc_lb_policy_factory_vtable round_robin_factory_vtable = {
- round_robin_factory_ref, round_robin_factory_unref, create_round_robin,
- "round_robin"};
-
-static grpc_lb_policy_factory round_robin_lb_policy_factory = {
- &round_robin_factory_vtable};
-
-grpc_lb_policy_factory *grpc_round_robin_lb_factory_create() {
- return &round_robin_lb_policy_factory;
-}
diff --git a/src/core/lib/client_config/lb_policies/round_robin.h b/src/core/lib/client_config/lb_policies/round_robin.h
deleted file mode 100644
index 52db1caa0c..0000000000
--- a/src/core/lib/client_config/lb_policies/round_robin.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H
-#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H
-
-#include "src/core/lib/client_config/lb_policy.h"
-
-extern int grpc_lb_round_robin_trace;
-
-#include "src/core/lib/client_config/lb_policy_factory.h"
-
-/** Returns a load balancing factory for the round robin policy */
-grpc_lb_policy_factory *grpc_round_robin_lb_factory_create();
-
-#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H */
diff --git a/src/core/lib/client_config/lb_policy.c b/src/core/lib/client_config/lb_policy.c
index ee20ccd76a..3d23669ec2 100644
--- a/src/core/lib/client_config/lb_policy.c
+++ b/src/core/lib/client_config/lb_policy.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/lb_policy.h b/src/core/lib/client_config/lb_policy.h
index 58a0a04d85..a63e8e68df 100644
--- a/src/core/lib/client_config/lb_policy.h
+++ b/src/core/lib/client_config/lb_policy.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/lb_policy_factory.c b/src/core/lib/client_config/lb_policy_factory.c
index 2ca6f42f89..92e1f5f08b 100644
--- a/src/core/lib/client_config/lb_policy_factory.c
+++ b/src/core/lib/client_config/lb_policy_factory.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,8 @@ void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory) {
}
grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy(
- grpc_lb_policy_factory* factory, grpc_lb_policy_args* args) {
+ grpc_exec_ctx* exec_ctx, grpc_lb_policy_factory* factory,
+ grpc_lb_policy_args* args) {
if (factory == NULL) return NULL;
- return factory->vtable->create_lb_policy(factory, args);
+ return factory->vtable->create_lb_policy(exec_ctx, factory, args);
}
diff --git a/src/core/lib/client_config/lb_policy_factory.h b/src/core/lib/client_config/lb_policy_factory.h
index 36eaf178d9..6f21912821 100644
--- a/src/core/lib/client_config/lb_policy_factory.h
+++ b/src/core/lib/client_config/lb_policy_factory.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,10 @@
#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H
#include "src/core/lib/client_config/lb_policy.h"
-#include "src/core/lib/client_config/subchannel.h"
+#include "src/core/lib/client_config/subchannel_factory.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+
+#include "src/core/lib/iomgr/exec_ctx.h"
typedef struct grpc_lb_policy_factory grpc_lb_policy_factory;
typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable;
@@ -47,8 +50,8 @@ struct grpc_lb_policy_factory {
};
typedef struct grpc_lb_policy_args {
- grpc_subchannel **subchannels;
- size_t num_subchannels;
+ grpc_resolved_addresses *addresses;
+ grpc_subchannel_factory *subchannel_factory;
} grpc_lb_policy_args;
struct grpc_lb_policy_factory_vtable {
@@ -56,7 +59,8 @@ struct grpc_lb_policy_factory_vtable {
void (*unref)(grpc_lb_policy_factory *factory);
/** Implementation of grpc_lb_policy_factory_create_lb_policy */
- grpc_lb_policy *(*create_lb_policy)(grpc_lb_policy_factory *factory,
+ grpc_lb_policy *(*create_lb_policy)(grpc_exec_ctx *exec_ctx,
+ grpc_lb_policy_factory *factory,
grpc_lb_policy_args *args);
/** Name for the LB policy this factory implements */
@@ -68,6 +72,7 @@ void grpc_lb_policy_factory_unref(grpc_lb_policy_factory *factory);
/** Create a lb_policy instance. */
grpc_lb_policy *grpc_lb_policy_factory_create_lb_policy(
- grpc_lb_policy_factory *factory, grpc_lb_policy_args *args);
+ grpc_exec_ctx *exec_ctx, grpc_lb_policy_factory *factory,
+ grpc_lb_policy_args *args);
#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_FACTORY_H */
diff --git a/src/core/lib/client_config/lb_policy_registry.c b/src/core/lib/client_config/lb_policy_registry.c
index 13acfe78cd..af396362a1 100644
--- a/src/core/lib/client_config/lb_policy_registry.c
+++ b/src/core/lib/client_config/lb_policy_registry.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,12 +40,7 @@
static grpc_lb_policy_factory *g_all_of_the_lb_policies[MAX_POLICIES];
static int g_number_of_lb_policies = 0;
-static grpc_lb_policy_factory *g_default_lb_policy_factory;
-
-void grpc_lb_policy_registry_init(grpc_lb_policy_factory *default_factory) {
- g_number_of_lb_policies = 0;
- g_default_lb_policy_factory = default_factory;
-}
+void grpc_lb_policy_registry_init(void) { g_number_of_lb_policies = 0; }
void grpc_lb_policy_registry_shutdown(void) {
int i;
@@ -79,10 +74,10 @@ static grpc_lb_policy_factory *lookup_factory(const char *name) {
return NULL;
}
-grpc_lb_policy *grpc_lb_policy_create(const char *name,
+grpc_lb_policy *grpc_lb_policy_create(grpc_exec_ctx *exec_ctx, const char *name,
grpc_lb_policy_args *args) {
grpc_lb_policy_factory *factory = lookup_factory(name);
grpc_lb_policy *lb_policy =
- grpc_lb_policy_factory_create_lb_policy(factory, args);
+ grpc_lb_policy_factory_create_lb_policy(exec_ctx, factory, args);
return lb_policy;
}
diff --git a/src/core/lib/client_config/lb_policy_registry.h b/src/core/lib/client_config/lb_policy_registry.h
index c251fd9f08..4b8495d8a1 100644
--- a/src/core/lib/client_config/lb_policy_registry.h
+++ b/src/core/lib/client_config/lb_policy_registry.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,11 @@
#define GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_REGISTRY_H
#include "src/core/lib/client_config/lb_policy_factory.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
/** Initialize the registry and set \a default_factory as the factory to be
* returned when no name is provided in a lookup */
-void grpc_lb_policy_registry_init(grpc_lb_policy_factory *default_factory);
+void grpc_lb_policy_registry_init(void);
void grpc_lb_policy_registry_shutdown(void);
/** Register a LB policy factory. */
@@ -48,7 +49,7 @@ void grpc_register_lb_policy(grpc_lb_policy_factory *factory);
*
* If \a name is NULL, the default factory from \a grpc_lb_policy_registry_init
* will be returned. */
-grpc_lb_policy *grpc_lb_policy_create(const char *name,
+grpc_lb_policy *grpc_lb_policy_create(grpc_exec_ctx *exec_ctx, const char *name,
grpc_lb_policy_args *args);
#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_LB_POLICY_REGISTRY_H */
diff --git a/src/core/lib/client_config/resolver.c b/src/core/lib/client_config/resolver.c
index 32f0643adb..b9eef5575f 100644
--- a/src/core/lib/client_config/resolver.c
+++ b/src/core/lib/client_config/resolver.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/resolver.h b/src/core/lib/client_config/resolver.h
index 1ee879293a..cf0bb2bc7a 100644
--- a/src/core/lib/client_config/resolver.h
+++ b/src/core/lib/client_config/resolver.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/resolver_factory.c b/src/core/lib/client_config/resolver_factory.c
index 0f76c664fa..001fa28536 100644
--- a/src/core/lib/client_config/resolver_factory.c
+++ b/src/core/lib/client_config/resolver_factory.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/resolver_factory.h b/src/core/lib/client_config/resolver_factory.h
index 7765c3c844..a5bca06475 100644
--- a/src/core/lib/client_config/resolver_factory.h
+++ b/src/core/lib/client_config/resolver_factory.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/resolver_registry.c b/src/core/lib/client_config/resolver_registry.c
index 29bd00c284..5f3db273b5 100644
--- a/src/core/lib/client_config/resolver_registry.c
+++ b/src/core/lib/client_config/resolver_registry.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -70,14 +70,11 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory) {
g_all_of_the_resolvers[g_number_of_resolvers++] = factory;
}
-static grpc_resolver_factory *lookup_factory(grpc_uri *uri) {
+static grpc_resolver_factory *lookup_factory(const char *name) {
int i;
- /* handling NULL uri's here simplifies grpc_resolver_create */
- if (!uri) return NULL;
-
for (i = 0; i < g_number_of_resolvers; i++) {
- if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i]->vtable->scheme)) {
+ if (0 == strcmp(name, g_all_of_the_resolvers[i]->vtable->scheme)) {
return g_all_of_the_resolvers[i];
}
}
@@ -85,6 +82,17 @@ static grpc_resolver_factory *lookup_factory(grpc_uri *uri) {
return NULL;
}
+grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name) {
+ grpc_resolver_factory *f = lookup_factory(name);
+ if (f) grpc_resolver_factory_ref(f);
+ return f;
+}
+
+static grpc_resolver_factory *lookup_factory_by_uri(grpc_uri *uri) {
+ if (!uri) return NULL;
+ return lookup_factory(uri->scheme);
+}
+
static grpc_resolver_factory *resolve_factory(const char *target,
grpc_uri **uri) {
char *tmp;
@@ -92,13 +100,13 @@ static grpc_resolver_factory *resolve_factory(const char *target,
GPR_ASSERT(uri != NULL);
*uri = grpc_uri_parse(target, 1);
- factory = lookup_factory(*uri);
+ factory = lookup_factory_by_uri(*uri);
if (factory == NULL) {
if (g_default_resolver_prefix != NULL) {
grpc_uri_destroy(*uri);
gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target);
*uri = grpc_uri_parse(tmp, 1);
- factory = lookup_factory(*uri);
+ factory = lookup_factory_by_uri(*uri);
if (factory == NULL) {
grpc_uri_destroy(grpc_uri_parse(target, 0));
grpc_uri_destroy(grpc_uri_parse(tmp, 0));
diff --git a/src/core/lib/client_config/resolver_registry.h b/src/core/lib/client_config/resolver_registry.h
index 22289ca6bd..36c4f2fe03 100644
--- a/src/core/lib/client_config/resolver_registry.h
+++ b/src/core/lib/client_config/resolver_registry.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,6 +58,10 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory);
grpc_resolver *grpc_resolver_create(
const char *target, grpc_subchannel_factory *subchannel_factory);
+/** Find a resolver factory given a name and return an (owned-by-the-caller)
+ * reference to it */
+grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name);
+
/** Given a target, return a (freshly allocated with gpr_malloc) string
representing the default authority to pass from a client. */
char *grpc_get_default_authority(const char *target);
diff --git a/src/core/lib/client_config/resolvers/dns_resolver.c b/src/core/lib/client_config/resolvers/dns_resolver.c
deleted file mode 100644
index ab445730ad..0000000000
--- a/src/core/lib/client_config/resolvers/dns_resolver.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/client_config/resolvers/dns_resolver.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/lib/client_config/lb_policy_registry.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-#include "src/core/lib/iomgr/timer.h"
-#include "src/core/lib/support/backoff.h"
-#include "src/core/lib/support/string.h"
-
-#define BACKOFF_MULTIPLIER 1.6
-#define BACKOFF_JITTER 0.2
-#define BACKOFF_MIN_SECONDS 1
-#define BACKOFF_MAX_SECONDS 120
-
-typedef struct {
- /** base class: must be first */
- grpc_resolver base;
- /** refcount */
- gpr_refcount refs;
- /** name to resolve */
- char *name;
- /** default port to use */
- char *default_port;
- /** subchannel factory */
- grpc_subchannel_factory *subchannel_factory;
- /** load balancing policy name */
- char *lb_policy_name;
-
- /** mutex guarding the rest of the state */
- gpr_mu mu;
- /** are we currently resolving? */
- int resolving;
- /** which version of resolved_config have we published? */
- int published_version;
- /** which version of resolved_config is current? */
- int resolved_version;
- /** pending next completion, or NULL */
- grpc_closure *next_completion;
- /** target config address for next completion */
- grpc_client_config **target_config;
- /** current (fully resolved) config */
- grpc_client_config *resolved_config;
- /** retry timer */
- bool have_retry_timer;
- grpc_timer retry_timer;
- /** retry backoff state */
- gpr_backoff backoff_state;
-} dns_resolver;
-
-static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
-
-static void dns_start_resolving_locked(dns_resolver *r);
-static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
- dns_resolver *r);
-
-static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
-static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
-static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
- grpc_client_config **target_config,
- grpc_closure *on_complete);
-
-static const grpc_resolver_vtable dns_resolver_vtable = {
- dns_destroy, dns_shutdown, dns_channel_saw_error, dns_next};
-
-static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) {
- dns_resolver *r = (dns_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- if (r->have_retry_timer) {
- grpc_timer_cancel(exec_ctx, &r->retry_timer);
- }
- if (r->next_completion != NULL) {
- *r->target_config = NULL;
- grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL);
- r->next_completion = NULL;
- }
- gpr_mu_unlock(&r->mu);
-}
-
-static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver) {
- dns_resolver *r = (dns_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- if (!r->resolving) {
- gpr_backoff_reset(&r->backoff_state);
- dns_start_resolving_locked(r);
- }
- gpr_mu_unlock(&r->mu);
-}
-
-static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
- grpc_client_config **target_config,
- grpc_closure *on_complete) {
- dns_resolver *r = (dns_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- GPR_ASSERT(!r->next_completion);
- r->next_completion = on_complete;
- r->target_config = target_config;
- if (r->resolved_version == 0 && !r->resolving) {
- gpr_backoff_reset(&r->backoff_state);
- dns_start_resolving_locked(r);
- } else {
- dns_maybe_finish_next_locked(exec_ctx, r);
- }
- gpr_mu_unlock(&r->mu);
-}
-
-static void dns_on_retry_timer(grpc_exec_ctx *exec_ctx, void *arg,
- bool success) {
- dns_resolver *r = arg;
-
- gpr_mu_lock(&r->mu);
- r->have_retry_timer = false;
- if (success) {
- if (!r->resolving) {
- dns_start_resolving_locked(r);
- }
- }
- gpr_mu_unlock(&r->mu);
-
- GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "retry-timer");
-}
-
-static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_resolved_addresses *addresses) {
- dns_resolver *r = arg;
- grpc_client_config *config = NULL;
- grpc_subchannel **subchannels;
- grpc_subchannel_args args;
- grpc_lb_policy *lb_policy;
- size_t i;
- gpr_mu_lock(&r->mu);
- GPR_ASSERT(r->resolving);
- r->resolving = 0;
- if (addresses != NULL) {
- grpc_lb_policy_args lb_policy_args;
- config = grpc_client_config_create();
- subchannels = gpr_malloc(sizeof(grpc_subchannel *) * addresses->naddrs);
- size_t naddrs = 0;
- for (i = 0; i < addresses->naddrs; i++) {
- memset(&args, 0, sizeof(args));
- args.addr = (struct sockaddr *)(addresses->addrs[i].addr);
- args.addr_len = (size_t)addresses->addrs[i].len;
- grpc_subchannel *subchannel = grpc_subchannel_factory_create_subchannel(
- exec_ctx, r->subchannel_factory, &args);
- if (subchannel != NULL) {
- subchannels[naddrs++] = subchannel;
- }
- }
- memset(&lb_policy_args, 0, sizeof(lb_policy_args));
- lb_policy_args.subchannels = subchannels;
- lb_policy_args.num_subchannels = naddrs;
- lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args);
- if (lb_policy != NULL) {
- grpc_client_config_set_lb_policy(config, lb_policy);
- GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction");
- }
- grpc_resolved_addresses_destroy(addresses);
- gpr_free(subchannels);
- } else {
- gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
- gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
- gpr_timespec timeout = gpr_time_sub(next_try, now);
- gpr_log(GPR_DEBUG, "dns resolution failed: retrying in %d.%09d seconds",
- timeout.tv_sec, timeout.tv_nsec);
- GPR_ASSERT(!r->have_retry_timer);
- r->have_retry_timer = true;
- GRPC_RESOLVER_REF(&r->base, "retry-timer");
- grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r,
- now);
- }
- if (r->resolved_config) {
- grpc_client_config_unref(exec_ctx, r->resolved_config);
- }
- r->resolved_config = config;
- r->resolved_version++;
- dns_maybe_finish_next_locked(exec_ctx, r);
- gpr_mu_unlock(&r->mu);
-
- GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving");
-}
-
-static void dns_start_resolving_locked(dns_resolver *r) {
- GRPC_RESOLVER_REF(&r->base, "dns-resolving");
- GPR_ASSERT(!r->resolving);
- r->resolving = 1;
- grpc_resolve_address(r->name, r->default_port, dns_on_resolved, r);
-}
-
-static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
- dns_resolver *r) {
- if (r->next_completion != NULL &&
- r->resolved_version != r->published_version) {
- *r->target_config = r->resolved_config;
- if (r->resolved_config) {
- grpc_client_config_ref(r->resolved_config);
- }
- grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL);
- r->next_completion = NULL;
- r->published_version = r->resolved_version;
- }
-}
-
-static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
- dns_resolver *r = (dns_resolver *)gr;
- gpr_mu_destroy(&r->mu);
- if (r->resolved_config) {
- grpc_client_config_unref(exec_ctx, r->resolved_config);
- }
- grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
- gpr_free(r->name);
- gpr_free(r->default_port);
- gpr_free(r->lb_policy_name);
- gpr_free(r);
-}
-
-static grpc_resolver *dns_create(grpc_resolver_args *args,
- const char *default_port,
- const char *lb_policy_name) {
- dns_resolver *r;
- const char *path = args->uri->path;
-
- if (0 != strcmp(args->uri->authority, "")) {
- gpr_log(GPR_ERROR, "authority based dns uri's not supported");
- return NULL;
- }
-
- if (path[0] == '/') ++path;
-
- r = gpr_malloc(sizeof(dns_resolver));
- memset(r, 0, sizeof(*r));
- gpr_ref_init(&r->refs, 1);
- gpr_mu_init(&r->mu);
- grpc_resolver_init(&r->base, &dns_resolver_vtable);
- r->name = gpr_strdup(path);
- r->default_port = gpr_strdup(default_port);
- r->subchannel_factory = args->subchannel_factory;
- gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER,
- BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000);
- grpc_subchannel_factory_ref(r->subchannel_factory);
- r->lb_policy_name = gpr_strdup(lb_policy_name);
- return &r->base;
-}
-
-/*
- * FACTORY
- */
-
-static void dns_factory_ref(grpc_resolver_factory *factory) {}
-
-static void dns_factory_unref(grpc_resolver_factory *factory) {}
-
-static grpc_resolver *dns_factory_create_resolver(
- grpc_resolver_factory *factory, grpc_resolver_args *args) {
- return dns_create(args, "https", "pick_first");
-}
-
-char *dns_factory_get_default_host_name(grpc_resolver_factory *factory,
- grpc_uri *uri) {
- const char *path = uri->path;
- if (path[0] == '/') ++path;
- return gpr_strdup(path);
-}
-
-static const grpc_resolver_factory_vtable dns_factory_vtable = {
- dns_factory_ref, dns_factory_unref, dns_factory_create_resolver,
- dns_factory_get_default_host_name, "dns"};
-static grpc_resolver_factory dns_resolver_factory = {&dns_factory_vtable};
-
-grpc_resolver_factory *grpc_dns_resolver_factory_create() {
- return &dns_resolver_factory;
-}
diff --git a/src/core/lib/client_config/resolvers/dns_resolver.h b/src/core/lib/client_config/resolvers/dns_resolver.h
deleted file mode 100644
index eb46e41c77..0000000000
--- a/src/core/lib/client_config/resolvers/dns_resolver.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H
-#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H
-
-#include "src/core/lib/client_config/resolver_factory.h"
-
-/** Create a dns resolver factory */
-grpc_resolver_factory *grpc_dns_resolver_factory_create(void);
-
-#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */
diff --git a/src/core/lib/client_config/resolvers/sockaddr_resolver.c b/src/core/lib/client_config/resolvers/sockaddr_resolver.c
deleted file mode 100644
index 66cddc3ed9..0000000000
--- a/src/core/lib/client_config/resolvers/sockaddr_resolver.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/lib/client_config/resolvers/sockaddr_resolver.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/lib/client_config/lb_policy_registry.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-#include "src/core/lib/iomgr/unix_sockets_posix.h"
-#include "src/core/lib/support/string.h"
-
-typedef struct {
- /** base class: must be first */
- grpc_resolver base;
- /** refcount */
- gpr_refcount refs;
- /** subchannel factory */
- grpc_subchannel_factory *subchannel_factory;
- /** load balancing policy name */
- char *lb_policy_name;
-
- /** the addresses that we've 'resolved' */
- struct sockaddr_storage *addrs;
- /** the corresponding length of the addresses */
- size_t *addrs_len;
- /** how many elements in \a addrs */
- size_t num_addrs;
-
- /** mutex guarding the rest of the state */
- gpr_mu mu;
- /** have we published? */
- int published;
- /** pending next completion, or NULL */
- grpc_closure *next_completion;
- /** target config address for next completion */
- grpc_client_config **target_config;
-} sockaddr_resolver;
-
-static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
-
-static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
- sockaddr_resolver *r);
-
-static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
-static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx,
- grpc_resolver *r);
-static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
- grpc_client_config **target_config,
- grpc_closure *on_complete);
-
-static const grpc_resolver_vtable sockaddr_resolver_vtable = {
- sockaddr_destroy, sockaddr_shutdown, sockaddr_channel_saw_error,
- sockaddr_next};
-
-static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver) {
- sockaddr_resolver *r = (sockaddr_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- if (r->next_completion != NULL) {
- *r->target_config = NULL;
- grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL);
- r->next_completion = NULL;
- }
- gpr_mu_unlock(&r->mu);
-}
-
-static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver) {
- sockaddr_resolver *r = (sockaddr_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- r->published = 0;
- sockaddr_maybe_finish_next_locked(exec_ctx, r);
- gpr_mu_unlock(&r->mu);
-}
-
-static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
- grpc_client_config **target_config,
- grpc_closure *on_complete) {
- sockaddr_resolver *r = (sockaddr_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- GPR_ASSERT(!r->next_completion);
- r->next_completion = on_complete;
- r->target_config = target_config;
- sockaddr_maybe_finish_next_locked(exec_ctx, r);
- gpr_mu_unlock(&r->mu);
-}
-
-static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
- sockaddr_resolver *r) {
- grpc_client_config *cfg;
- grpc_lb_policy *lb_policy;
- grpc_lb_policy_args lb_policy_args;
- grpc_subchannel **subchannels;
- grpc_subchannel_args args;
-
- if (r->next_completion != NULL && !r->published) {
- size_t i;
- cfg = grpc_client_config_create();
- subchannels = gpr_malloc(sizeof(grpc_subchannel *) * r->num_addrs);
- for (i = 0; i < r->num_addrs; i++) {
- memset(&args, 0, sizeof(args));
- args.addr = (struct sockaddr *)&r->addrs[i];
- args.addr_len = r->addrs_len[i];
- subchannels[i] = grpc_subchannel_factory_create_subchannel(
- exec_ctx, r->subchannel_factory, &args);
- }
- memset(&lb_policy_args, 0, sizeof(lb_policy_args));
- lb_policy_args.subchannels = subchannels;
- lb_policy_args.num_subchannels = r->num_addrs;
- lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args);
- gpr_free(subchannels);
- grpc_client_config_set_lb_policy(cfg, lb_policy);
- GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "sockaddr");
- r->published = 1;
- *r->target_config = cfg;
- grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL);
- r->next_completion = NULL;
- }
-}
-
-static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
- sockaddr_resolver *r = (sockaddr_resolver *)gr;
- gpr_mu_destroy(&r->mu);
- grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
- gpr_free(r->addrs);
- gpr_free(r->addrs_len);
- gpr_free(r->lb_policy_name);
- gpr_free(r);
-}
-
-static char *ip_get_default_authority(grpc_uri *uri) {
- const char *path = uri->path;
- if (path[0] == '/') ++path;
- return gpr_strdup(path);
-}
-
-static char *ipv4_get_default_authority(grpc_resolver_factory *factory,
- grpc_uri *uri) {
- return ip_get_default_authority(uri);
-}
-
-static char *ipv6_get_default_authority(grpc_resolver_factory *factory,
- grpc_uri *uri) {
- return ip_get_default_authority(uri);
-}
-
-static int parse_ipv4(grpc_uri *uri, struct sockaddr_storage *addr,
- size_t *len) {
- const char *host_port = uri->path;
- char *host;
- char *port;
- int port_num;
- int result = 0;
- struct sockaddr_in *in = (struct sockaddr_in *)addr;
-
- if (*host_port == '/') ++host_port;
- if (!gpr_split_host_port(host_port, &host, &port)) {
- return 0;
- }
-
- memset(in, 0, sizeof(*in));
- *len = sizeof(*in);
- in->sin_family = AF_INET;
- if (inet_pton(AF_INET, host, &in->sin_addr) == 0) {
- gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host);
- goto done;
- }
-
- if (port != NULL) {
- if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
- port_num > 65535) {
- gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port);
- goto done;
- }
- in->sin_port = htons((uint16_t)port_num);
- } else {
- gpr_log(GPR_ERROR, "no port given for ipv4 scheme");
- goto done;
- }
-
- result = 1;
-done:
- gpr_free(host);
- gpr_free(port);
- return result;
-}
-
-static int parse_ipv6(grpc_uri *uri, struct sockaddr_storage *addr,
- size_t *len) {
- const char *host_port = uri->path;
- char *host;
- char *port;
- int port_num;
- int result = 0;
- struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
-
- if (*host_port == '/') ++host_port;
- if (!gpr_split_host_port(host_port, &host, &port)) {
- return 0;
- }
-
- memset(in6, 0, sizeof(*in6));
- *len = sizeof(*in6);
- in6->sin6_family = AF_INET6;
- if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
- gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
- goto done;
- }
-
- if (port != NULL) {
- if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
- port_num > 65535) {
- gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port);
- goto done;
- }
- in6->sin6_port = htons((uint16_t)port_num);
- } else {
- gpr_log(GPR_ERROR, "no port given for ipv6 scheme");
- goto done;
- }
-
- result = 1;
-done:
- gpr_free(host);
- gpr_free(port);
- return result;
-}
-
-static void do_nothing(void *ignored) {}
-
-static grpc_resolver *sockaddr_create(
- grpc_resolver_args *args, const char *default_lb_policy_name,
- int parse(grpc_uri *uri, struct sockaddr_storage *dst, size_t *len)) {
- size_t i;
- int errors_found = 0; /* GPR_FALSE */
- sockaddr_resolver *r;
- gpr_slice path_slice;
- gpr_slice_buffer path_parts;
-
- if (0 != strcmp(args->uri->authority, "")) {
- gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
- args->uri->scheme);
- return NULL;
- }
-
- r = gpr_malloc(sizeof(sockaddr_resolver));
- memset(r, 0, sizeof(*r));
-
- r->lb_policy_name = NULL;
- if (0 != strcmp(args->uri->query, "")) {
- gpr_slice query_slice;
- gpr_slice_buffer query_parts;
-
- query_slice =
- gpr_slice_new(args->uri->query, strlen(args->uri->query), do_nothing);
- gpr_slice_buffer_init(&query_parts);
- gpr_slice_split(query_slice, "=", &query_parts);
- GPR_ASSERT(query_parts.count == 2);
- if (0 == gpr_slice_str_cmp(query_parts.slices[0], "lb_policy")) {
- r->lb_policy_name = gpr_dump_slice(query_parts.slices[1], GPR_DUMP_ASCII);
- }
- gpr_slice_buffer_destroy(&query_parts);
- gpr_slice_unref(query_slice);
- }
- if (r->lb_policy_name == NULL) {
- r->lb_policy_name = gpr_strdup(default_lb_policy_name);
- }
-
- path_slice =
- gpr_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
- gpr_slice_buffer_init(&path_parts);
-
- gpr_slice_split(path_slice, ",", &path_parts);
- r->num_addrs = path_parts.count;
- r->addrs = gpr_malloc(sizeof(struct sockaddr_storage) * r->num_addrs);
- r->addrs_len = gpr_malloc(sizeof(*r->addrs_len) * r->num_addrs);
-
- for (i = 0; i < r->num_addrs; i++) {
- grpc_uri ith_uri = *args->uri;
- char *part_str = gpr_dump_slice(path_parts.slices[i], GPR_DUMP_ASCII);
- ith_uri.path = part_str;
- if (!parse(&ith_uri, &r->addrs[i], &r->addrs_len[i])) {
- errors_found = 1; /* GPR_TRUE */
- }
- gpr_free(part_str);
- if (errors_found) break;
- }
-
- gpr_slice_buffer_destroy(&path_parts);
- gpr_slice_unref(path_slice);
- if (errors_found) {
- gpr_free(r->lb_policy_name);
- gpr_free(r->addrs);
- gpr_free(r->addrs_len);
- gpr_free(r);
- return NULL;
- }
-
- gpr_ref_init(&r->refs, 1);
- gpr_mu_init(&r->mu);
- grpc_resolver_init(&r->base, &sockaddr_resolver_vtable);
- r->subchannel_factory = args->subchannel_factory;
- grpc_subchannel_factory_ref(r->subchannel_factory);
-
- return &r->base;
-}
-
-/*
- * FACTORY
- */
-
-static void sockaddr_factory_ref(grpc_resolver_factory *factory) {}
-
-static void sockaddr_factory_unref(grpc_resolver_factory *factory) {}
-
-#define DECL_FACTORY(name, prefix) \
- static grpc_resolver *name##_factory_create_resolver( \
- grpc_resolver_factory *factory, grpc_resolver_args *args) { \
- return sockaddr_create(args, "pick_first", prefix##parse_##name); \
- } \
- static const grpc_resolver_factory_vtable name##_factory_vtable = { \
- sockaddr_factory_ref, sockaddr_factory_unref, \
- name##_factory_create_resolver, prefix##name##_get_default_authority, \
- #name}; \
- static grpc_resolver_factory name##_resolver_factory = { \
- &name##_factory_vtable}; \
- grpc_resolver_factory *grpc_##name##_resolver_factory_create() { \
- return &name##_resolver_factory; \
- }
-
-#ifdef GPR_HAVE_UNIX_SOCKET
-DECL_FACTORY(unix, grpc_)
-#endif
-DECL_FACTORY(ipv4, ) DECL_FACTORY(ipv6, )
diff --git a/src/core/lib/client_config/resolvers/sockaddr_resolver.h b/src/core/lib/client_config/resolvers/sockaddr_resolver.h
deleted file mode 100644
index 45c55bd160..0000000000
--- a/src/core/lib/client_config/resolvers/sockaddr_resolver.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H
-#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/lib/client_config/resolver_factory.h"
-
-grpc_resolver_factory *grpc_ipv4_resolver_factory_create(void);
-
-grpc_resolver_factory *grpc_ipv6_resolver_factory_create(void);
-
-#ifdef GPR_POSIX_SOCKET
-/** Create a unix resolver factory */
-grpc_resolver_factory *grpc_unix_resolver_factory_create(void);
-#endif
-
-#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H */
diff --git a/src/core/lib/client_config/resolvers/zookeeper_resolver.c b/src/core/lib/client_config/resolvers/zookeeper_resolver.c
deleted file mode 100644
index 3bb0bbdf5c..0000000000
--- a/src/core/lib/client_config/resolvers/zookeeper_resolver.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/client_config/resolvers/zookeeper_resolver.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/string_util.h>
-
-#include <grpc/grpc_zookeeper.h>
-#include <zookeeper/zookeeper.h>
-
-#include "src/core/lib/client_config/lb_policy_registry.h"
-#include "src/core/lib/client_config/resolver_registry.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-#include "src/core/lib/json/json.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/surface/api_trace.h"
-
-/** Zookeeper session expiration time in milliseconds */
-#define GRPC_ZOOKEEPER_SESSION_TIMEOUT 15000
-
-typedef struct {
- /** base class: must be first */
- grpc_resolver base;
- /** refcount */
- gpr_refcount refs;
- /** name to resolve */
- char *name;
- /** subchannel factory */
- grpc_subchannel_factory *subchannel_factory;
- /** load balancing policy name */
- char *lb_policy_name;
-
- /** mutex guarding the rest of the state */
- gpr_mu mu;
- /** are we currently resolving? */
- int resolving;
- /** which version of resolved_config have we published? */
- int published_version;
- /** which version of resolved_config is current? */
- int resolved_version;
- /** pending next completion, or NULL */
- grpc_closure *next_completion;
- /** target config address for next completion */
- grpc_client_config **target_config;
- /** current (fully resolved) config */
- grpc_client_config *resolved_config;
-
- /** zookeeper handle */
- zhandle_t *zookeeper_handle;
- /** zookeeper resolved addresses */
- grpc_resolved_addresses *resolved_addrs;
- /** total number of addresses to be resolved */
- int resolved_total;
- /** number of addresses resolved */
- int resolved_num;
-} zookeeper_resolver;
-
-static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
-
-static void zookeeper_start_resolving_locked(zookeeper_resolver *r);
-static void zookeeper_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
- zookeeper_resolver *r);
-
-static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r);
-static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx,
- grpc_resolver *r);
-static void zookeeper_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r,
- grpc_client_config **target_config,
- grpc_closure *on_complete);
-
-static const grpc_resolver_vtable zookeeper_resolver_vtable = {
- zookeeper_destroy, zookeeper_shutdown, zookeeper_channel_saw_error,
- zookeeper_next};
-
-static void zookeeper_shutdown(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver) {
- zookeeper_resolver *r = (zookeeper_resolver *)resolver;
- grpc_closure *call = NULL;
- gpr_mu_lock(&r->mu);
- if (r->next_completion != NULL) {
- *r->target_config = NULL;
- call = r->next_completion;
- r->next_completion = NULL;
- }
- zookeeper_close(r->zookeeper_handle);
- gpr_mu_unlock(&r->mu);
- if (call != NULL) {
- call->cb(exec_ctx, call->cb_arg, 1);
- }
-}
-
-static void zookeeper_channel_saw_error(grpc_exec_ctx *exec_ctx,
- grpc_resolver *resolver) {
- zookeeper_resolver *r = (zookeeper_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- if (r->resolving == 0) {
- zookeeper_start_resolving_locked(r);
- }
- gpr_mu_unlock(&r->mu);
-}
-
-static void zookeeper_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver,
- grpc_client_config **target_config,
- grpc_closure *on_complete) {
- zookeeper_resolver *r = (zookeeper_resolver *)resolver;
- gpr_mu_lock(&r->mu);
- GPR_ASSERT(r->next_completion == NULL);
- r->next_completion = on_complete;
- r->target_config = target_config;
- if (r->resolved_version == 0 && r->resolving == 0) {
- zookeeper_start_resolving_locked(r);
- } else {
- zookeeper_maybe_finish_next_locked(exec_ctx, r);
- }
- gpr_mu_unlock(&r->mu);
-}
-
-/** Zookeeper global watcher for connection management
- TODO: better connection management besides logs */
-static void zookeeper_global_watcher(zhandle_t *zookeeper_handle, int type,
- int state, const char *path,
- void *watcher_ctx) {
- if (type == ZOO_SESSION_EVENT) {
- if (state == ZOO_EXPIRED_SESSION_STATE) {
- gpr_log(GPR_ERROR, "Zookeeper session expired");
- } else if (state == ZOO_AUTH_FAILED_STATE) {
- gpr_log(GPR_ERROR, "Zookeeper authentication failed");
- }
- }
-}
-
-/** Zookeeper watcher triggered by changes to watched nodes
- Once triggered, it tries to resolve again to get updated addresses */
-static void zookeeper_watcher(zhandle_t *zookeeper_handle, int type, int state,
- const char *path, void *watcher_ctx) {
- if (watcher_ctx != NULL) {
- zookeeper_resolver *r = (zookeeper_resolver *)watcher_ctx;
- if (state == ZOO_CONNECTED_STATE) {
- gpr_mu_lock(&r->mu);
- if (r->resolving == 0) {
- zookeeper_start_resolving_locked(r);
- }
- gpr_mu_unlock(&r->mu);
- }
- }
-}
-
-/** Callback function after getting all resolved addresses
- Creates a subchannel for each address */
-static void zookeeper_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_resolved_addresses *addresses) {
- zookeeper_resolver *r = arg;
- grpc_client_config *config = NULL;
- grpc_subchannel **subchannels;
- grpc_subchannel_args args;
- grpc_lb_policy *lb_policy;
- size_t i;
- if (addresses != NULL) {
- grpc_lb_policy_args lb_policy_args;
- config = grpc_client_config_create();
- subchannels = gpr_malloc(sizeof(grpc_subchannel *) * addresses->naddrs);
- for (i = 0; i < addresses->naddrs; i++) {
- memset(&args, 0, sizeof(args));
- args.addr = (struct sockaddr *)(addresses->addrs[i].addr);
- args.addr_len = addresses->addrs[i].len;
- subchannels[i] = grpc_subchannel_factory_create_subchannel(
- exec_ctx, r->subchannel_factory, &args);
- }
- lb_policy_args.subchannels = subchannels;
- lb_policy_args.num_subchannels = addresses->naddrs;
- lb_policy = grpc_lb_policy_create(r->lb_policy_name, &lb_policy_args);
- grpc_client_config_set_lb_policy(config, lb_policy);
- GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction");
- grpc_resolved_addresses_destroy(addresses);
- gpr_free(subchannels);
- }
- gpr_mu_lock(&r->mu);
- GPR_ASSERT(r->resolving == 1);
- r->resolving = 0;
- if (r->resolved_config != NULL) {
- grpc_client_config_unref(exec_ctx, r->resolved_config);
- }
- r->resolved_config = config;
- r->resolved_version++;
- zookeeper_maybe_finish_next_locked(exec_ctx, r);
- gpr_mu_unlock(&r->mu);
-
- GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "zookeeper-resolving");
-}
-
-/** Callback function for each DNS resolved address */
-static void zookeeper_dns_resolved(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_resolved_addresses *addresses) {
- size_t i;
- zookeeper_resolver *r = arg;
- int resolve_done = 0;
-
- gpr_mu_lock(&r->mu);
- r->resolved_num++;
- r->resolved_addrs->addrs =
- gpr_realloc(r->resolved_addrs->addrs,
- sizeof(grpc_resolved_address) *
- (r->resolved_addrs->naddrs + addresses->naddrs));
- for (i = 0; i < addresses->naddrs; i++) {
- memcpy(r->resolved_addrs->addrs[i + r->resolved_addrs->naddrs].addr,
- addresses->addrs[i].addr, addresses->addrs[i].len);
- r->resolved_addrs->addrs[i + r->resolved_addrs->naddrs].len =
- addresses->addrs[i].len;
- }
-
- r->resolved_addrs->naddrs += addresses->naddrs;
- grpc_resolved_addresses_destroy(addresses);
-
- /** Wait for all addresses to be resolved */
- resolve_done = (r->resolved_num == r->resolved_total);
- gpr_mu_unlock(&r->mu);
- if (resolve_done) {
- zookeeper_on_resolved(exec_ctx, r, r->resolved_addrs);
- }
-}
-
-/** Parses JSON format address of a zookeeper node */
-static char *zookeeper_parse_address(const char *value, size_t value_len) {
- grpc_json *json;
- grpc_json *cur;
- const char *host;
- const char *port;
- char *buffer;
- char *address = NULL;
-
- buffer = gpr_malloc(value_len);
- memcpy(buffer, value, value_len);
- json = grpc_json_parse_string_with_len(buffer, value_len);
- if (json != NULL) {
- host = NULL;
- port = NULL;
- for (cur = json->child; cur != NULL; cur = cur->next) {
- if (!strcmp(cur->key, "host")) {
- host = cur->value;
- if (port != NULL) {
- break;
- }
- } else if (!strcmp(cur->key, "port")) {
- port = cur->value;
- if (host != NULL) {
- break;
- }
- }
- }
- if (host != NULL && port != NULL) {
- gpr_asprintf(&address, "%s:%s", host, port);
- }
- grpc_json_destroy(json);
- }
- gpr_free(buffer);
-
- return address;
-}
-
-static void zookeeper_get_children_node_completion(int rc, const char *value,
- int value_len,
- const struct Stat *stat,
- const void *arg) {
- char *address = NULL;
- zookeeper_resolver *r = (zookeeper_resolver *)arg;
- int resolve_done = 0;
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-
- if (rc != 0) {
- gpr_log(GPR_ERROR, "Error in getting a child node of %s", r->name);
- grpc_exec_ctx_finish(&exec_ctx);
- return;
- }
-
- address = zookeeper_parse_address(value, (size_t)value_len);
- if (address != NULL) {
- /** Further resolves address by DNS */
- grpc_resolve_address(address, NULL, zookeeper_dns_resolved, r);
- gpr_free(address);
- } else {
- gpr_log(GPR_ERROR, "Error in resolving a child node of %s", r->name);
- gpr_mu_lock(&r->mu);
- r->resolved_total--;
- resolve_done = (r->resolved_num == r->resolved_total);
- gpr_mu_unlock(&r->mu);
- if (resolve_done) {
- zookeeper_on_resolved(&exec_ctx, r, r->resolved_addrs);
- }
- }
-
- grpc_exec_ctx_finish(&exec_ctx);
-}
-
-static void zookeeper_get_children_completion(
- int rc, const struct String_vector *children, const void *arg) {
- char *path;
- int status;
- int i;
- zookeeper_resolver *r = (zookeeper_resolver *)arg;
-
- if (rc != 0) {
- gpr_log(GPR_ERROR, "Error in getting zookeeper children of %s", r->name);
- return;
- }
-
- if (children->count == 0) {
- gpr_log(GPR_ERROR, "Error in resolving zookeeper address %s", r->name);
- return;
- }
-
- r->resolved_addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
- r->resolved_addrs->addrs = NULL;
- r->resolved_addrs->naddrs = 0;
- r->resolved_total = children->count;
-
- /** TODO: Replace expensive heap allocation with stack
- if we can get maximum length of zookeeper path */
- for (i = 0; i < children->count; i++) {
- gpr_asprintf(&path, "%s/%s", r->name, children->data[i]);
- status = zoo_awget(r->zookeeper_handle, path, zookeeper_watcher, r,
- zookeeper_get_children_node_completion, r);
- gpr_free(path);
- if (status != 0) {
- gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", path);
- }
- }
-}
-
-static void zookeeper_get_node_completion(int rc, const char *value,
- int value_len,
- const struct Stat *stat,
- const void *arg) {
- int status;
- char *address = NULL;
- zookeeper_resolver *r = (zookeeper_resolver *)arg;
- r->resolved_addrs = NULL;
- r->resolved_total = 0;
- r->resolved_num = 0;
-
- if (rc != 0) {
- gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", r->name);
- return;
- }
-
- /** If zookeeper node of path r->name does not have address
- (i.e. service node), get its children */
- address = zookeeper_parse_address(value, (size_t)value_len);
- if (address != NULL) {
- r->resolved_addrs = gpr_malloc(sizeof(grpc_resolved_addresses));
- r->resolved_addrs->addrs = NULL;
- r->resolved_addrs->naddrs = 0;
- r->resolved_total = 1;
- /** Further resolves address by DNS */
- grpc_resolve_address(address, NULL, zookeeper_dns_resolved, r);
- gpr_free(address);
- return;
- }
-
- status = zoo_awget_children(r->zookeeper_handle, r->name, zookeeper_watcher,
- r, zookeeper_get_children_completion, r);
- if (status != 0) {
- gpr_log(GPR_ERROR, "Error in getting zookeeper children of %s", r->name);
- }
-}
-
-static void zookeeper_resolve_address(zookeeper_resolver *r) {
- int status;
- status = zoo_awget(r->zookeeper_handle, r->name, zookeeper_watcher, r,
- zookeeper_get_node_completion, r);
- if (status != 0) {
- gpr_log(GPR_ERROR, "Error in getting zookeeper node %s", r->name);
- }
-}
-
-static void zookeeper_start_resolving_locked(zookeeper_resolver *r) {
- GRPC_RESOLVER_REF(&r->base, "zookeeper-resolving");
- GPR_ASSERT(r->resolving == 0);
- r->resolving = 1;
- zookeeper_resolve_address(r);
-}
-
-static void zookeeper_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
- zookeeper_resolver *r) {
- if (r->next_completion != NULL &&
- r->resolved_version != r->published_version) {
- *r->target_config = r->resolved_config;
- if (r->resolved_config != NULL) {
- grpc_client_config_ref(r->resolved_config);
- }
- grpc_exec_ctx_enqueue(exec_ctx, r->next_completion, true, NULL);
- r->next_completion = NULL;
- r->published_version = r->resolved_version;
- }
-}
-
-static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
- zookeeper_resolver *r = (zookeeper_resolver *)gr;
- gpr_mu_destroy(&r->mu);
- if (r->resolved_config != NULL) {
- grpc_client_config_unref(exec_ctx, r->resolved_config);
- }
- grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
- gpr_free(r->name);
- gpr_free(r->lb_policy_name);
- gpr_free(r);
-}
-
-static grpc_resolver *zookeeper_create(grpc_resolver_args *args,
- const char *lb_policy_name) {
- zookeeper_resolver *r;
- size_t length;
- char *path = args->uri->path;
-
- if (0 == strcmp(args->uri->authority, "")) {
- gpr_log(GPR_ERROR, "No authority specified in zookeeper uri");
- return NULL;
- }
-
- /** Removes the trailing slash if exists */
- length = strlen(path);
- if (length > 1 && path[length - 1] == '/') {
- path[length - 1] = 0;
- }
-
- r = gpr_malloc(sizeof(zookeeper_resolver));
- memset(r, 0, sizeof(*r));
- gpr_ref_init(&r->refs, 1);
- gpr_mu_init(&r->mu);
- grpc_resolver_init(&r->base, &zookeeper_resolver_vtable);
- r->name = gpr_strdup(path);
-
- r->subchannel_factory = args->subchannel_factory;
- grpc_subchannel_factory_ref(r->subchannel_factory);
-
- r->lb_policy_name = gpr_strdup(lb_policy_name);
-
- /** Initializes zookeeper client */
- zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
- r->zookeeper_handle =
- zookeeper_init(args->uri->authority, zookeeper_global_watcher,
- GRPC_ZOOKEEPER_SESSION_TIMEOUT, 0, 0, 0);
- if (r->zookeeper_handle == NULL) {
- gpr_log(GPR_ERROR, "Unable to connect to zookeeper server");
- return NULL;
- }
-
- return &r->base;
-}
-
-static void zookeeper_plugin_init() {
- grpc_register_resolver_type(grpc_zookeeper_resolver_factory_create());
-}
-
-void grpc_zookeeper_register() {
- GRPC_API_TRACE("grpc_zookeeper_register(void)", 0, ());
- grpc_register_plugin(zookeeper_plugin_init, NULL);
-}
-
-/*
- * FACTORY
- */
-
-static void zookeeper_factory_ref(grpc_resolver_factory *factory) {}
-
-static void zookeeper_factory_unref(grpc_resolver_factory *factory) {}
-
-static char *zookeeper_factory_get_default_hostname(
- grpc_resolver_factory *factory, grpc_uri *uri) {
- return NULL;
-}
-
-static grpc_resolver *zookeeper_factory_create_resolver(
- grpc_resolver_factory *factory, grpc_resolver_args *args) {
- return zookeeper_create(args, "pick_first");
-}
-
-static const grpc_resolver_factory_vtable zookeeper_factory_vtable = {
- zookeeper_factory_ref, zookeeper_factory_unref,
- zookeeper_factory_create_resolver, zookeeper_factory_get_default_hostname,
- "zookeeper"};
-
-static grpc_resolver_factory zookeeper_resolver_factory = {
- &zookeeper_factory_vtable};
-
-grpc_resolver_factory *grpc_zookeeper_resolver_factory_create() {
- return &zookeeper_resolver_factory;
-}
diff --git a/src/core/lib/client_config/resolvers/zookeeper_resolver.h b/src/core/lib/client_config/resolvers/zookeeper_resolver.h
deleted file mode 100644
index 7ee7604360..0000000000
--- a/src/core/lib/client_config/resolvers/zookeeper_resolver.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H
-#define GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H
-
-#include "src/core/lib/client_config/resolver_factory.h"
-
-/** Create a zookeeper resolver factory */
-grpc_resolver_factory *grpc_zookeeper_resolver_factory_create(void);
-
-#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H */
diff --git a/src/core/lib/client_config/subchannel.c b/src/core/lib/client_config/subchannel.c
index 41242f0dd7..47c53a16ba 100644
--- a/src/core/lib/client_config/subchannel.c
+++ b/src/core/lib/client_config/subchannel.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/subchannel.h b/src/core/lib/client_config/subchannel.h
index b4f545be52..68aeff39a1 100644
--- a/src/core/lib/client_config/subchannel.h
+++ b/src/core/lib/client_config/subchannel.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/subchannel_factory.c b/src/core/lib/client_config/subchannel_factory.c
index 727a48a6c8..541368ec96 100644
--- a/src/core/lib/client_config/subchannel_factory.c
+++ b/src/core/lib/client_config/subchannel_factory.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/subchannel_factory.h b/src/core/lib/client_config/subchannel_factory.h
index 3ba2f860fe..96d68a2079 100644
--- a/src/core/lib/client_config/subchannel_factory.h
+++ b/src/core/lib/client_config/subchannel_factory.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/core/lib/client_config/uri_parser.c b/src/core/lib/client_config/uri_parser.c
index d3228dec5f..6bec70da2d 100644
--- a/src/core/lib/client_config/uri_parser.c
+++ b/src/core/lib/client_config/uri_parser.c
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,8 +38,12 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
#include <grpc/support/string_util.h>
+#include "src/core/lib/support/string.h"
+
/** a size_t default value... maps to all 1's */
#define NOT_SET (~(size_t)0)
@@ -133,6 +137,51 @@ static int parse_fragment_or_query(const char *uri_text, size_t *i) {
return 1;
}
+static void do_nothing(void *ignored) {}
+static void parse_query_parts(grpc_uri *uri) {
+ static const char *QUERY_PARTS_SEPARATOR = "&";
+ static const char *QUERY_PARTS_VALUE_SEPARATOR = "=";
+ GPR_ASSERT(uri->query != NULL);
+ if (uri->query[0] == '\0') {
+ uri->query_parts = NULL;
+ uri->query_parts_values = NULL;
+ uri->num_query_parts = 0;
+ return;
+ }
+ gpr_slice query_slice =
+ gpr_slice_new(uri->query, strlen(uri->query), do_nothing);
+ gpr_slice_buffer query_parts; /* the &-separated elements of the query */
+ gpr_slice_buffer query_param_parts; /* the =-separated subelements */
+
+ gpr_slice_buffer_init(&query_parts);
+ gpr_slice_buffer_init(&query_param_parts);
+
+ gpr_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts);
+ uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *));
+ uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *));
+ uri->num_query_parts = query_parts.count;
+ for (size_t i = 0; i < query_parts.count; i++) {
+ gpr_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR,
+ &query_param_parts);
+ GPR_ASSERT(query_param_parts.count > 0);
+ uri->query_parts[i] =
+ gpr_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII);
+ if (query_param_parts.count > 1) {
+ /* TODO(dgq): only the first value after the separator is considered.
+ * Perhaps all chars after the first separator for the query part should
+ * be included, even if they include the separator. */
+ uri->query_parts_values[i] =
+ gpr_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII);
+ } else {
+ uri->query_parts_values[i] = NULL;
+ }
+ gpr_slice_buffer_reset_and_unref(&query_param_parts);
+ }
+ gpr_slice_buffer_destroy(&query_parts);
+ gpr_slice_buffer_destroy(&query_param_parts);
+ gpr_slice_unref(query_slice);
+}
+
grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
grpc_uri *uri;
size_t scheme_begin = 0;
@@ -227,16 +276,35 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
uri->path = copy_component(uri_text, path_begin, path_end);
uri->query = copy_component(uri_text, query_begin, query_end);
uri->fragment = copy_component(uri_text, fragment_begin, fragment_end);
+ parse_query_parts(uri);
return uri;
}
+const char *grpc_uri_get_query_arg(const grpc_uri *uri, const char *key) {
+ GPR_ASSERT(key != NULL);
+ if (key[0] == '\0') return NULL;
+
+ for (size_t i = 0; i < uri->num_query_parts; ++i) {
+ if (0 == strcmp(key, uri->query_parts[i])) {
+ return uri->query_parts_values[i];
+ }
+ }
+ return NULL;
+}
+
void grpc_uri_destroy(grpc_uri *uri) {
if (!uri) return;
gpr_free(uri->scheme);
gpr_free(uri->authority);
gpr_free(uri->path);
gpr_free(uri->query);
+ for (size_t i = 0; i < uri->num_query_parts; ++i) {
+ gpr_free(uri->query_parts[i]);
+ gpr_free(uri->query_parts_values[i]);
+ }
+ gpr_free(uri->query_parts);
+ gpr_free(uri->query_parts_values);
gpr_free(uri->fragment);
gpr_free(uri);
}
diff --git a/src/core/lib/client_config/uri_parser.h b/src/core/lib/client_config/uri_parser.h
index d70d451e60..5d6785d293 100644
--- a/src/core/lib/client_config/uri_parser.h
+++ b/src/core/lib/client_config/uri_parser.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016, Google Inc.
+ * Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,17 +34,29 @@
#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_URI_PARSER_H
#define GRPC_CORE_LIB_CLIENT_CONFIG_URI_PARSER_H
+#include <stddef.h>
+
typedef struct {
char *scheme;
char *authority;
char *path;
char *query;
+ /** Query substrings separated by '&' */
+ char **query_parts;
+ /** Number of elements in \a query_parts and \a query_parts_values */
+ size_t num_query_parts;
+ /** Split each query part by '='. NULL if not present. */
+ char **query_parts_values;
char *fragment;
} grpc_uri;
/** parse a uri, return NULL on failure */
grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors);
+/** return the part of a query string after the '=' in "?key=xxx&...", or NULL
+ * if key is not present */
+const char *grpc_uri_get_query_arg(const grpc_uri *uri, const char *key);
+
/** destroy a uri */
void grpc_uri_destroy(grpc_uri *uri);