1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18
19#ifndef BRPC_CHANNEL_H
20#define BRPC_CHANNEL_H
21
22// To brpc developers: This is a header included by user, don't depend
23// on internal structures, use opaque pointers instead.
24
25#include <ostream> // std::ostream
26#include "bthread/errno.h" // Redefine errno
27#include "butil/intrusive_ptr.hpp" // butil::intrusive_ptr
28#include "butil/ptr_container.h"
29#include "brpc/ssl_options.h" // ChannelSSLOptions
30#include "brpc/channel_base.h" // ChannelBase
31#include "brpc/adaptive_protocol_type.h" // AdaptiveProtocolType
32#include "brpc/adaptive_connection_type.h" // AdaptiveConnectionType
33#include "brpc/socket_id.h" // SocketId
34#include "brpc/controller.h" // brpc::Controller
35#include "brpc/details/profiler_linker.h"
36#include "brpc/retry_policy.h"
37#include "brpc/naming_service_filter.h"
38
39namespace brpc {
40
41struct ChannelOptions {
42 // Constructed with default options.
43 ChannelOptions();
44
45 // Issue error when a connection is not established after so many
46 // milliseconds. -1 means wait indefinitely.
47 // Default: 200 (milliseconds)
48 // Maximum: 0x7fffffff (roughly 30 days)
49 int32_t connect_timeout_ms;
50
51 // Max duration of RPC over this Channel. -1 means wait indefinitely.
52 // Overridable by Controller.set_timeout_ms().
53 // Default: 500 (milliseconds)
54 // Maximum: 0x7fffffff (roughly 30 days)
55 int32_t timeout_ms;
56
57 // Send another request if RPC does not finish after so many milliseconds.
58 // Overridable by Controller.set_backup_request_ms().
59 // The request will be sent to a different server by best effort.
60 // If timeout_ms is set and backup_request_ms >= timeout_ms, backup request
61 // will never be sent.
62 // backup request does NOT imply server-side cancelation.
63 // Default: -1 (disabled)
64 // Maximum: 0x7fffffff (roughly 30 days)
65 int32_t backup_request_ms;
66
67 // Retry limit for RPC over this Channel. <=0 means no retry.
68 // Overridable by Controller.set_max_retry().
69 // Default: 3
70 // Maximum: INT_MAX
71 int max_retry;
72
73 // When the error rate of a server node is too high, isolate the node.
74 // Note that this isolation is GLOBAL, the node will become unavailable
75 // for all channels running in this process during the isolation.
76 // Default: false
77 bool enable_circuit_breaker;
78
79 // Serialization protocol, defined in src/brpc/options.proto
80 // NOTE: You can assign name of the protocol to this field as well, for
81 // Example: options.protocol = "baidu_std";
82 AdaptiveProtocolType protocol;
83
84 // Type of connection to server. If unset, use the default connection type
85 // of the protocol.
86 // NOTE: You can assign name of the type to this field as well, for
87 // Example: options.connection_type = "single";
88 // Possible values: "single", "pooled", "short".
89 AdaptiveConnectionType connection_type;
90
91 // Channel.Init() succeeds even if there's no server in the NamingService.
92 // E.g. the BNS directory is empty. All RPC over the channel will fail before
93 // new nodes being added to the NamingService.
94 // Default: true (false before r32470)
95 bool succeed_without_server;
96 // Print a log when above situation happens.
97 // Default: true.
98 bool log_succeed_without_server;
99
100 // SSL related options. Refer to `ChannelSSLOptions' for details
101 bool has_ssl_options() const { return _ssl_options != NULL; }
102 const ChannelSSLOptions& ssl_options() const { return *_ssl_options.get(); }
103 ChannelSSLOptions* mutable_ssl_options();
104
105 // Turn on authentication for this channel if `auth' is not NULL.
106 // Note `auth' will not be deleted by channel and must remain valid when
107 // the channel is being used.
108 // Default: NULL
109 const Authenticator* auth;
110
111 // Customize the error code that should be retried. The interface is
112 // defined in src/brpc/retry_policy.h
113 // This object is NOT owned by channel and should remain valid when
114 // channel is used.
115 // Default: NULL
116 const RetryPolicy* retry_policy;
117
118 // Filter ServerNodes (i.e. based on `tag' field of `ServerNode')
119 // which are generated by NamingService. The interface is defined
120 // in src/brpc/naming_service_filter.h
121 // This object is NOT owned by channel and should remain valid when
122 // channel is used.
123 // Default: NULL
124 const NamingServiceFilter* ns_filter;
125
126 // Channels with same connection_group share connections.
127 // In other words, set to a different value to stop sharing connections.
128 // Case-sensitive, leading and trailing spaces are ignored.
129 // Default: ""
130 std::string connection_group;
131
132private:
133 // SSLOptions is large and not often used, allocate it on heap to
134 // prevent ChannelOptions from being bloated in most cases.
135 butil::PtrContainer<ChannelSSLOptions> _ssl_options;
136};
137
138// A Channel represents a communication line to one server or multiple servers
139// which can be used to call that Server's services. Servers may be running
140// on another machines. Normally, you should not call a Channel directly, but
141// instead construct a stub Service wrapping it.
142// Example:
143// brpc::Channel channel;
144// channel.Init("bns://rdev.matrix.all", "rr", NULL/*default options*/);
145// MyService_Stub stub(&channel);
146// stub.MyMethod(&controller, &request, &response, NULL);
147class Channel : public ChannelBase {
148friend class Controller;
149friend class SelectiveChannel;
150public:
151 Channel(ProfilerLinker = ProfilerLinker());
152 ~Channel();
153
154 // Connect this channel to a single server whose address is given by the
155 // first parameter. Use default options if `options' is NULL.
156 int Init(butil::EndPoint server_addr_and_port, const ChannelOptions* options);
157 int Init(const char* server_addr_and_port, const ChannelOptions* options);
158 int Init(const char* server_addr, int port, const ChannelOptions* options);
159
160 // Connect this channel to a group of servers whose addresses can be
161 // accessed via `naming_service_url' according to its protocol. Use the
162 // method specified by `load_balancer_name' to distribute traffic to
163 // servers. Use default options if `options' is NULL.
164 // Supported naming service("protocol://service_name"):
165 // bns://<node-name> # Baidu Naming Service
166 // file://<file-path> # load addresses from the file
167 // list://addr1,addr2,... # use the addresses separated by comma
168 // http://<url> # Domain Naming Service, aka DNS.
169 // Supported load balancer:
170 // rr # round robin, choose next server
171 // random # randomly choose a server
172 // la # locality aware
173 // c_murmurhash/c_md5 # consistent hashing with murmurhash3/md5
174 // "" or NULL # treat `naming_service_url' as `server_addr_and_port'
175 // # Init(xxx, "", options) and Init(xxx, NULL, options)
176 // # are exactly same with Init(xxx, options)
177 int Init(const char* naming_service_url,
178 const char* load_balancer_name,
179 const ChannelOptions* options);
180
181 // Call `method' of the remote service with `request' as input, and
182 // `response' as output. `controller' contains options and extra data.
183 // If `done' is not NULL, this method returns after request was sent
184 // and `done->Run()' will be called when the call finishes, otherwise
185 // caller blocks until the call finishes.
186 void CallMethod(const google::protobuf::MethodDescriptor* method,
187 google::protobuf::RpcController* controller,
188 const google::protobuf::Message* request,
189 google::protobuf::Message* response,
190 google::protobuf::Closure* done);
191
192 // Get current options.
193 const ChannelOptions& options() const { return _options; }
194
195 void Describe(std::ostream&, const DescribeOptions&) const;
196
197 // Sum of weights of servers that this channel connects to.
198 int Weight();
199
200protected:
201 int CheckHealth();
202
203 bool SingleServer() const { return _lb.get() == NULL; }
204
205 // Pick a server using `lb' and then send RPC. Wait for response when
206 // sending synchronous RPC.
207 // NOTE: DO NOT directly use `controller' after this call when
208 // sending asynchronous RPC (controller->_done != NULL) since
209 // user callback `done' could be called when it returns and
210 // therefore destroy the `controller' inside `done'
211 static void CallMethodImpl(Controller* controller, SharedLoadBalancer* lb);
212
213 int InitChannelOptions(const ChannelOptions* options);
214 int InitSingle(const butil::EndPoint& server_addr_and_port,
215 const char* raw_server_address,
216 const ChannelOptions* options);
217
218 butil::EndPoint _server_address;
219 SocketId _server_id;
220 Protocol::SerializeRequest _serialize_request;
221 Protocol::PackRequest _pack_request;
222 Protocol::GetMethodName _get_method_name;
223 // This will be shared between channel and controllers that
224 // are in the middle of RPC procedure using this channel.
225 // It will be destroyed after channel's destruction and all
226 // the RPC above has finished
227 butil::intrusive_ptr<SharedLoadBalancer> _lb;
228 ChannelOptions _options;
229 int _preferred_index;
230};
231
232enum ChannelOwnership {
233 OWNS_CHANNEL,
234 DOESNT_OWN_CHANNEL
235};
236
237} // namespace brpc
238
239#endif // BRPC_CHANNEL_H
240