blob: 357d8317adfc8eed1744d7e9221396f918778c9f [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
yang-g8c2be9f2015-08-19 16:28:09 -070034#include <grpc++/channel.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035
yangg59dfc902014-12-19 14:00:14 -080036#include <memory>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080037
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080038#include <grpc++/client_context.h>
Craig Tiller50950712015-02-09 10:38:38 -080039#include <grpc++/completion_queue.h>
Craig Tiller20f4af22015-02-10 09:52:15 -080040#include <grpc++/impl/call.h>
David Garcia Quintas08a0a332016-01-21 01:04:36 -080041#include <grpc++/impl/codegen/completion_queue_tag.h>
David Garcia Quintase1300de2016-01-27 18:41:26 -080042#include <grpc++/impl/grpc_library.h>
43#include <grpc++/impl/rpc_method.h>
44#include <grpc++/security/credentials.h>
yang-g9e2f90c2015-08-21 15:35:03 -070045#include <grpc++/support/channel_arguments.h>
46#include <grpc++/support/config.h>
47#include <grpc++/support/status.h>
48#include <grpc++/support/time.h>
David Garcia Quintase1300de2016-01-27 18:41:26 -080049#include <grpc/grpc.h>
Craig Tillerb37d53e2016-10-26 16:16:35 -070050#include <grpc/slice.h>
Mark D. Roth4bbdda42016-11-09 14:40:22 -080051#include <grpc/support/alloc.h>
Craig Tiller28b72422016-10-26 21:15:29 -070052#include <grpc/support/log.h>
Craig Tiller9533d042016-03-25 17:11:06 -070053#include "src/core/lib/profiling/timers.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080054
55namespace grpc {
56
David Garcia Quintasd79ef3a2016-01-28 00:21:27 -080057static internal::GrpcLibraryInitializer g_gli_initializer;
yang-gd556da92015-07-31 15:59:04 -070058Channel::Channel(const grpc::string& host, grpc_channel* channel)
David Garcia Quintase1300de2016-01-27 18:41:26 -080059 : host_(host), c_channel_(channel) {
David Garcia Quintasd79ef3a2016-01-28 00:21:27 -080060 g_gli_initializer.summon();
David Garcia Quintase1300de2016-01-27 18:41:26 -080061}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080062
63Channel::~Channel() { grpc_channel_destroy(c_channel_); }
64
Mark D. Roth4bbdda42016-11-09 14:40:22 -080065namespace {
66
67grpc::string GetChannelInfoField(grpc_channel* channel,
68 grpc_channel_info* channel_info,
69 char*** channel_info_field) {
70 char* value = NULL;
71 memset(channel_info, 0, sizeof(*channel_info));
72 *channel_info_field = &value;
73 grpc_channel_get_info(channel, channel_info);
74 if (value == NULL) return "";
75 grpc::string result = value;
76 gpr_free(value);
77 return result;
78}
79
80} // namespace
81
82grpc::string Channel::GetLoadBalancingPolicyName() const {
83 grpc_channel_info channel_info;
84 return GetChannelInfoField(c_channel_, &channel_info,
85 &channel_info.lb_policy_name);
86}
87
88grpc::string Channel::GetServiceConfigJSON() const {
89 grpc_channel_info channel_info;
90 return GetChannelInfoField(c_channel_, &channel_info,
91 &channel_info.service_config_json);
92}
93
Craig Tiller47c83fd2015-02-21 22:45:35 -080094Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
95 CompletionQueue* cq) {
yang-g37ce0342015-08-12 11:46:26 -070096 const bool kRegistered = method.channel_tag() && context->authority().empty();
yang-g0c034a02015-08-11 11:46:32 -070097 grpc_call* c_call = NULL;
yang-g37ce0342015-08-12 11:46:26 -070098 if (kRegistered) {
yang-g0c034a02015-08-11 11:46:32 -070099 c_call = grpc_channel_create_registered_call(
100 c_channel_, context->propagate_from_call_,
101 context->propagation_options_.c_bitmask(), cq->cq(),
Nicolas "Pixel" Nobled53b3892015-08-13 19:20:39 +0200102 method.channel_tag(), context->raw_deadline(), nullptr);
yang-g0c034a02015-08-11 11:46:32 -0700103 } else {
104 const char* host_str = NULL;
105 if (!context->authority().empty()) {
yang-g2f543f22015-08-19 15:14:17 -0700106 host_str = context->authority_.c_str();
yang-g0c034a02015-08-11 11:46:32 -0700107 } else if (!host_.empty()) {
108 host_str = host_.c_str();
109 }
110 c_call = grpc_channel_create_call(c_channel_, context->propagate_from_call_,
111 context->propagation_options_.c_bitmask(),
112 cq->cq(), method.name(), host_str,
Nicolas "Pixel" Nobled53b3892015-08-13 19:20:39 +0200113 context->raw_deadline(), nullptr);
yang-g0c034a02015-08-11 11:46:32 -0700114 }
yang-g9a009f22015-07-29 11:38:18 -0700115 grpc_census_call_set_context(c_call, context->census_context());
Craig Tiller1fb99552015-04-27 08:55:08 -0700116 context->set_call(c_call, shared_from_this());
Craig Tiller50950712015-02-09 10:38:38 -0800117 return Call(c_call, this, cq);
118}
119
Craig Tiller50a7a682015-06-04 12:53:40 -0700120void Channel::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
Craig Tiller50950712015-02-09 10:38:38 -0800121 static const size_t MAX_OPS = 8;
Craig Tiller50a7a682015-06-04 12:53:40 -0700122 size_t nops = 0;
123 grpc_op cops[MAX_OPS];
Craig Tiller50a7a682015-06-04 12:53:40 -0700124 ops->FillOps(cops, &nops);
Craig Tiller50950712015-02-09 10:38:38 -0800125 GPR_ASSERT(GRPC_CALL_OK ==
Nicolas "Pixel" Nobleebb51402015-07-23 02:41:33 +0200126 grpc_call_start_batch(call->call(), cops, nops, ops, nullptr));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800127}
128
Craig Tiller277d3cf2015-04-14 14:04:51 -0700129void* Channel::RegisterMethod(const char* method) {
Craig Tillerd6c98df2015-08-18 09:33:44 -0700130 return grpc_channel_register_call(
131 c_channel_, method, host_.empty() ? NULL : host_.c_str(), nullptr);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800132}
133
yang-ga73dc1c2015-08-05 14:24:00 -0700134grpc_connectivity_state Channel::GetState(bool try_to_connect) {
135 return grpc_channel_check_connectivity_state(c_channel_, try_to_connect);
136}
137
yang-g36f59652015-08-05 15:15:18 -0700138namespace {
Vijay Paic0b2acb2016-11-01 16:31:56 -0700139class TagSaver final : public CompletionQueueTag {
yang-g36f59652015-08-05 15:15:18 -0700140 public:
141 explicit TagSaver(void* tag) : tag_(tag) {}
Vijay Paic0b2acb2016-11-01 16:31:56 -0700142 ~TagSaver() override {}
143 bool FinalizeResult(void** tag, bool* status) override {
yang-g36f59652015-08-05 15:15:18 -0700144 *tag = tag_;
145 delete this;
146 return true;
147 }
Craig Tillerd6c98df2015-08-18 09:33:44 -0700148
yang-g36f59652015-08-05 15:15:18 -0700149 private:
150 void* tag_;
151};
152
yang-gc8abca82015-08-06 22:50:16 -0700153} // namespace
154
155void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
156 gpr_timespec deadline,
157 CompletionQueue* cq, void* tag) {
yang-g36f59652015-08-05 15:15:18 -0700158 TagSaver* tag_saver = new TagSaver(tag);
yang-gc8abca82015-08-06 22:50:16 -0700159 grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline,
160 cq->cq(), tag_saver);
yang-g36f59652015-08-05 15:15:18 -0700161}
162
yang-gc8abca82015-08-06 22:50:16 -0700163bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed,
164 gpr_timespec deadline) {
yang-g36f59652015-08-05 15:15:18 -0700165 CompletionQueue cq;
166 bool ok = false;
167 void* tag = NULL;
yang-gc8abca82015-08-06 22:50:16 -0700168 NotifyOnStateChangeImpl(last_observed, deadline, &cq, NULL);
yang-g36f59652015-08-05 15:15:18 -0700169 cq.Next(&tag, &ok);
170 GPR_ASSERT(tag == NULL);
171 return ok;
172}
173
Craig Tiller190d3602015-02-18 09:23:38 -0800174} // namespace grpc