Google Cloud C++ Client  1.33.0
C++ Client Library for Google Cloud Platform
connection_options.h
Go to the documentation of this file.
1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_CONNECTION_OPTIONS_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_CONNECTION_OPTIONS_H
17 
18 #include "google/cloud/common_options.h"
19 #include "google/cloud/completion_queue.h"
20 #include "google/cloud/grpc_options.h"
21 #include "google/cloud/internal/algorithm.h"
22 #include "google/cloud/internal/background_threads_impl.h"
23 #include "google/cloud/options.h"
24 #include "google/cloud/status_or.h"
25 #include "google/cloud/tracing_options.h"
26 #include "google/cloud/version.h"
27 #include <grpcpp/grpcpp.h>
28 #include <functional>
29 #include <memory>
30 #include <set>
31 #include <string>
32 
33 namespace google {
34 namespace cloud {
36 
37 template <typename ConnectionTraits>
38 class ConnectionOptions;
39 
40 namespace internal {
41 std::set<std::string> DefaultTracingComponents();
42 TracingOptions DefaultTracingOptions();
43 std::unique_ptr<BackgroundThreads> DefaultBackgroundThreads(std::size_t);
44 template <typename ConnectionTraits>
45 Options MakeOptions(ConnectionOptions<ConnectionTraits>);
46 } // namespace internal
47 
48 /**
49  * The configuration parameters for client connections.
50  */
51 template <typename ConnectionTraits>
52 class ConnectionOptions {
53  public:
54  /// The default options, using `grpc::GoogleDefaultCredentials()`.
55  ConnectionOptions() : ConnectionOptions(grpc::GoogleDefaultCredentials()) {}
56 
57  /// The default options, using an explicit credentials object.
59  std::shared_ptr<grpc::ChannelCredentials> credentials)
60  : opts_(Options{}
61  .set<GrpcCredentialOption>(std::move(credentials))
63  internal::DefaultTracingComponents())
65  internal::DefaultTracingOptions())
66  .template set<EndpointOption>(
67  ConnectionTraits::default_endpoint())
68  .template set<GrpcNumChannelsOption>(
69  ConnectionTraits::default_num_channels())),
70  user_agent_prefix_(ConnectionTraits::user_agent_prefix()) {}
71 
72  /// Change the gRPC credentials value.
73  ConnectionOptions& set_credentials(
74  std::shared_ptr<grpc::ChannelCredentials> v) {
75  opts_.set<GrpcCredentialOption>(std::move(v));
76  return *this;
77  }
78 
79  /// The gRPC credentials used by clients configured with this object.
80  std::shared_ptr<grpc::ChannelCredentials> credentials() const {
81  return opts_.get<GrpcCredentialOption>();
82  }
83 
84  /**
85  * Change the gRPC endpoint.
86  *
87  * In almost all cases the default is the correct endpoint to use.
88  * Applications may need to be changed to (1) test against a fake or
89  * simulator, or (2) to use a beta or EAP version of the service.
90  *
91  * The default value is set by `ConnectionTraits::default_endpoint()`.
92  */
93  ConnectionOptions& set_endpoint(std::string v) {
94  opts_.set<EndpointOption>(std::move(v));
95  return *this;
96  }
97 
98  /// The endpoint used by clients configured with this object.
99  std::string const& endpoint() const { return opts_.get<EndpointOption>(); }
100 
101  /**
102  * The number of transport channels to create.
103  *
104  * Some transports limit the number of simultaneous calls in progress on a
105  * channel (for gRPC the limit is 100). Increasing the number of channels
106  * thus increases the number of operations that can be in progress in
107  * parallel.
108  *
109  * The default value is set by `ConnectionTraits::default_num_channels()`.
110  */
111  int num_channels() const { return opts_.get<GrpcNumChannelsOption>(); }
112 
113  /// Set the value for `num_channels()`.
114  ConnectionOptions& set_num_channels(int num_channels) {
115  opts_.set<GrpcNumChannelsOption>(num_channels);
116  return *this;
117  }
118 
119  /**
120  * Return whether tracing is enabled for the given @p component.
121  *
122  * The C++ clients can log interesting events to help library and application
123  * developers troubleshoot problems. This flag returns true if tracing should
124  * be enabled by clients configured with this option.
125  */
126  bool tracing_enabled(std::string const& component) const {
127  return internal::Contains(opts_.get<TracingComponentsOption>(), component);
128  }
129 
130  /// Enable tracing for @p component in clients configured with this object.
131  ConnectionOptions& enable_tracing(std::string const& component) {
132  opts_.lookup<TracingComponentsOption>().insert(component);
133  return *this;
134  }
135 
136  /// Disable tracing for @p component in clients configured with this object.
137  ConnectionOptions& disable_tracing(std::string const& component) {
138  opts_.lookup<TracingComponentsOption>().erase(component);
139  return *this;
140  }
141 
142  /// Return the set of tracing components.
143  std::set<std::string> const& components() const {
145  }
146 
147  /// Return the options for use when tracing RPCs.
150  }
151 
152  /**
153  * Define the gRPC channel domain for clients configured with this object.
154  *
155  * In some cases applications may want to use a separate gRPC connections for
156  * different clients. gRPC may share the connection used by separate channels
157  * created with the same configuration. The client objects created with this
158  * object will create gRPC channels configured with
159  * `grpc.channel_pooling_domain` set to the value returned by
160  * `channel_pool_domain()`. gRPC channels with different values for
161  * `grpc.channel_pooling_domain` are guaranteed to use different connections.
162  * Note that there is no guarantee that channels with the same value will have
163  * the same connection though.
164  *
165  * This option might be useful for applications that want to segregate traffic
166  * for whatever reason.
167  */
168  std::string const& channel_pool_domain() const {
169  return channel_pool_domain_;
170  }
171 
172  /// Set the value for `channel_pool_domain()`.
173  ConnectionOptions& set_channel_pool_domain(std::string v) {
174  channel_pool_domain_ = std::move(v);
175  return *this;
176  }
177 
178  /**
179  * Prepend @p prefix to the user-agent string.
180  *
181  * Libraries or services that use Cloud C++ clients may want to set their own
182  * user-agent prefix. This can help them develop telemetry information about
183  * number of users running particular versions of their system or library.
184  */
185  ConnectionOptions& add_user_agent_prefix(std::string prefix) {
186  prefix += " ";
187  prefix += user_agent_prefix_;
188  user_agent_prefix_ = std::move(prefix);
189  return *this;
190  }
191 
192  /// Return the current value for the user agent string.
193  std::string const& user_agent_prefix() const { return user_agent_prefix_; }
194 
195  /**
196  * Create a new `grpc::ChannelArguments` configured with the options in this
197  * object.
198  *
199  * The caller would typically pass this argument to
200  * `grpc::CreateCustomChannel` and create one more more gRPC channels.
201  */
202  grpc::ChannelArguments CreateChannelArguments() const {
203  return internal::MakeChannelArguments(internal::MakeOptions(*this));
204  }
205 
206  /**
207  * Set the number of background threads.
208  *
209  * @note This value is not used if `DisableBackgroundThreads()` is called.
210  */
211  ConnectionOptions& set_background_thread_pool_size(std::size_t s) {
212  background_thread_pool_size_ = s;
213  return *this;
214  }
215  std::size_t background_thread_pool_size() const {
216  return background_thread_pool_size_;
217  }
218 
219  /**
220  * Configure the connection to use @p cq for all background work.
221  *
222  * Connections need to perform background work on behalf of the application.
223  * Normally they just create a background thread and a `CompletionQueue` for
224  * this work, but the application may need more fine-grained control of their
225  * threads. In this case the application can provide the `CompletionQueue` and
226  * it assumes responsibility for creating one or more threads blocked on
227  * `CompletionQueue::Run()`.
228  */
229  ConnectionOptions& DisableBackgroundThreads(
230  google::cloud::CompletionQueue const& cq) {
231  background_threads_factory_ = [cq] {
232  return absl::make_unique<internal::CustomerSuppliedBackgroundThreads>(cq);
233  };
234  return *this;
235  }
236 
237  using BackgroundThreadsFactory = ::google::cloud::BackgroundThreadsFactory;
238  BackgroundThreadsFactory background_threads_factory() const {
239  if (background_threads_factory_) return background_threads_factory_;
240  auto const s = background_thread_pool_size_;
241  return [s] { return internal::DefaultBackgroundThreads(s); };
242  }
243 
244  private:
245  template <typename T>
246  friend Options internal::MakeOptions(ConnectionOptions<T>);
247 
248  Options opts_;
249 
250  // These are fields that have different semantics than the equivalent ones in
251  // the new `Options` class.
252  std::string user_agent_prefix_;
253  std::string channel_pool_domain_;
254  std::size_t background_thread_pool_size_ = 0;
255  BackgroundThreadsFactory background_threads_factory_;
256 };
257 
258 namespace internal {
259 
260 template <typename ConnectionTraits>
261 Options MakeOptions(ConnectionOptions<ConnectionTraits> old) {
262  Options opts = std::move(old.opts_);
263  opts.set<UserAgentProductsOption>({std::move(old.user_agent_prefix_)});
265  old.background_threads_factory());
266  if (!old.channel_pool_domain_.empty()) {
267  // To get a different channel pool one just needs to set any channel
268  // parameter to a different value. Newer versions of gRPC include a macro
269  // for this purpose (GRPC_ARG_CHANNEL_POOL_DOMAIN). As we are compiling
270  // against older versions in some cases, we use the actual value.
271  opts.set<GrpcChannelArgumentsOption>(
272  {{"grpc.channel_pooling_domain", std::move(old.channel_pool_domain_)}});
273  }
274  return opts;
275 }
276 
277 } // namespace internal
278 
280 } // namespace cloud
281 } // namespace google
282 
283 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_CONNECTION_OPTIONS_H