Skip to content
This repository was archived by the owner on Dec 8, 2021. It is now read-only.

Commit b24ab4b

Browse files
authored
refactor: copy ConnectionOptions from spanner (#165)
The plan is to copy the class here, and later remove it from spanner, we need it for Cloud Pub/Sub too. This is not strictly a copy, the defaults are different for each service, for example: the endpoint. The class is a template, parametized by traits to set the defaults. Each client library will instantiate this class with the right set of defaults.
1 parent d96ba55 commit b24ab4b

File tree

7 files changed

+572
-1
lines changed

7 files changed

+572
-1
lines changed

google/cloud/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ if (GOOGLE_CLOUD_CPP_ENABLE_GRPC_UTILS)
319319
background_threads.h
320320
completion_queue.cc
321321
completion_queue.h
322+
connection_options.cc
323+
connection_options.h
322324
grpc_error_delegate.cc
323325
grpc_error_delegate.h
324326
grpc_utils/async_operation.h
@@ -355,7 +357,9 @@ if (GOOGLE_CLOUD_CPP_ENABLE_GRPC_UTILS)
355357
# List the unit tests, then setup the targets and dependencies.
356358
set(google_cloud_cpp_grpc_utils_unit_tests
357359
# cmake-format: sort
358-
completion_queue_test.cc grpc_error_delegate_test.cc
360+
completion_queue_test.cc
361+
connection_options_test.cc
362+
grpc_error_delegate_test.cc
359363
internal/background_threads_impl_test.cc)
360364

361365
# Export the list of unit tests so the Bazel BUILD file can pick it up.

google/cloud/connection_options.cc

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
#include "google/cloud/connection_options.h"
16+
#include "google/cloud/internal/getenv.h"
17+
#include "google/cloud/internal/make_unique.h"
18+
#include "google/cloud/log.h"
19+
#include <sstream>
20+
21+
namespace google {
22+
namespace cloud {
23+
inline namespace GOOGLE_CLOUD_CPP_NS {
24+
namespace internal {
25+
std::set<std::string> DefaultTracingComponents() {
26+
auto tracing =
27+
google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_ENABLE_TRACING");
28+
if (!tracing.has_value()) return {};
29+
std::set<std::string> result;
30+
std::istringstream is{*tracing};
31+
std::string token;
32+
while (std::getline(is, token, ',')) {
33+
result.insert(token);
34+
}
35+
return result;
36+
}
37+
38+
TracingOptions DefaultTracingOptions() {
39+
auto tracing_options =
40+
google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_TRACING_OPTIONS");
41+
if (!tracing_options) return {};
42+
return TracingOptions{}.SetOptions(*tracing_options);
43+
}
44+
45+
void DefaultLogging() {
46+
if (google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_ENABLE_CLOG")
47+
.has_value()) {
48+
google::cloud::LogSink::EnableStdClog();
49+
}
50+
}
51+
52+
std::unique_ptr<BackgroundThreads> DefaultBackgroundThreads() {
53+
return google::cloud::internal::make_unique<
54+
AutomaticallyCreatedBackgroundThreads>();
55+
}
56+
57+
} // namespace internal
58+
} // namespace GOOGLE_CLOUD_CPP_NS
59+
} // namespace cloud
60+
} // namespace google

google/cloud/connection_options.h

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
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/completion_queue.h"
19+
#include "google/cloud/internal/background_threads_impl.h"
20+
#include "google/cloud/status_or.h"
21+
#include "google/cloud/tracing_options.h"
22+
#include <grpcpp/grpcpp.h>
23+
#include <functional>
24+
#include <memory>
25+
#include <set>
26+
#include <string>
27+
28+
namespace google {
29+
namespace cloud {
30+
inline namespace GOOGLE_CLOUD_CPP_NS {
31+
namespace internal {
32+
std::set<std::string> DefaultTracingComponents();
33+
TracingOptions DefaultTracingOptions();
34+
void DefaultLogging();
35+
std::unique_ptr<BackgroundThreads> DefaultBackgroundThreads();
36+
} // namespace internal
37+
38+
/**
39+
* The configuration parameters for client connections.
40+
*/
41+
template <typename ConnectionTraits>
42+
class ConnectionOptions {
43+
public:
44+
/// The default options, using `grpc::GoogleDefaultCredentials()`.
45+
ConnectionOptions() : ConnectionOptions(grpc::GoogleDefaultCredentials()) {}
46+
47+
/// The default options, using an explicit credentials object.
48+
explicit ConnectionOptions(
49+
std::shared_ptr<grpc::ChannelCredentials> credentials)
50+
: credentials_(std::move(credentials)),
51+
endpoint_(ConnectionTraits::default_endpoint()),
52+
num_channels_(ConnectionTraits::default_num_channels()),
53+
tracing_components_(internal::DefaultTracingComponents()),
54+
tracing_options_(internal::DefaultTracingOptions()),
55+
user_agent_prefix_(ConnectionTraits::user_agent_prefix()),
56+
background_threads_factory_(internal::DefaultBackgroundThreads) {
57+
internal::DefaultLogging();
58+
}
59+
60+
/// Change the gRPC credentials value.
61+
ConnectionOptions& set_credentials(
62+
std::shared_ptr<grpc::ChannelCredentials> v) {
63+
credentials_ = std::move(v);
64+
return *this;
65+
}
66+
67+
/// The gRPC credentials used by clients configured with this object.
68+
std::shared_ptr<grpc::ChannelCredentials> credentials() const {
69+
return credentials_;
70+
}
71+
72+
/**
73+
* Change the gRPC endpoint.
74+
*
75+
* In almost all cases the default is the correct endpoint to use.
76+
* Applications may need to be changed to (1) test against a fake or
77+
* simulator, or (2) to use a beta or EAP version of the service.
78+
*
79+
* The default value is set by `ConnectionTraits::default_endpoint()`.
80+
*/
81+
ConnectionOptions& set_endpoint(std::string v) {
82+
endpoint_ = std::move(v);
83+
return *this;
84+
}
85+
86+
/// The endpoint used by clients configured with this object.
87+
std::string const& endpoint() const { return endpoint_; }
88+
89+
/**
90+
* The number of transport channels to create.
91+
*
92+
* Some transports limit the number of simultaneous calls in progress on a
93+
* channel (for gRPC the limit is 100). Increasing the number of channels
94+
* thus increases the number of operations that can be in progress in
95+
* parallel.
96+
*
97+
* The default value is set by `ConnectionTraits::default_num_channels()`.
98+
*/
99+
int num_channels() const { return num_channels_; }
100+
101+
/// Set the value for `num_channels()`.
102+
ConnectionOptions& set_num_channels(int num_channels) {
103+
num_channels_ = num_channels;
104+
return *this;
105+
}
106+
107+
/**
108+
* Return whether tracing is enabled for the given @p component.
109+
*
110+
* The C++ clients can log interesting events to help library and application
111+
* developers troubleshoot problems. This flag returns true if tracing should
112+
* be enabled by clients configured with this option.
113+
*/
114+
bool tracing_enabled(std::string const& component) const {
115+
return tracing_components_.find(component) != tracing_components_.end();
116+
}
117+
118+
/// Enable tracing for @p component in clients configured with this object.
119+
ConnectionOptions& enable_tracing(std::string const& component) {
120+
tracing_components_.insert(component);
121+
return *this;
122+
}
123+
124+
/// Disable tracing for @p component in clients configured with this object.
125+
ConnectionOptions& disable_tracing(std::string const& component) {
126+
tracing_components_.erase(component);
127+
return *this;
128+
}
129+
130+
/// Return the options for use when tracing RPCs.
131+
TracingOptions const& tracing_options() const { return tracing_options_; }
132+
133+
/**
134+
* Define the gRPC channel domain for clients configured with this object.
135+
*
136+
* In some cases applications may want to use a separate gRPC connections for
137+
* different clients. gRPC may share the connection used by separate channels
138+
* created with the same configuration. The client objects created with this
139+
* object will create gRPC channels configured with
140+
* `grpc.channel_pooling_domain` set to the value returned by
141+
* `channel_pool_domain()`. gRPC channels with different values for
142+
* `grpc.channel_pooling_domain` are guaranteed to use different connections.
143+
* Note that there is no guarantee that channels with the same value will have
144+
* the same connection though.
145+
*
146+
* This option might be useful for applications that want to segregate traffic
147+
* for whatever reason.
148+
*/
149+
std::string const& channel_pool_domain() const {
150+
return channel_pool_domain_;
151+
}
152+
153+
/// Set the value for `channel_pool_domain()`.
154+
ConnectionOptions& set_channel_pool_domain(std::string v) {
155+
channel_pool_domain_ = std::move(v);
156+
return *this;
157+
}
158+
159+
/**
160+
* Prepend @p prefix to the user-agent string.
161+
*
162+
* Libraries or services that use Cloud C++ clients may want to set their own
163+
* user-agent prefix. This can help them develop telemetry information about
164+
* number of users running particular versions of their system or library.
165+
*/
166+
ConnectionOptions& add_user_agent_prefix(std::string prefix) {
167+
prefix += " ";
168+
prefix += user_agent_prefix_;
169+
user_agent_prefix_ = std::move(prefix);
170+
return *this;
171+
}
172+
173+
/// Return the current value for the user agent string.
174+
std::string const& user_agent_prefix() const { return user_agent_prefix_; }
175+
176+
/**
177+
* Create a new `grpc::ChannelArguments` configured with the options in this
178+
* object.
179+
*
180+
* The caller would typically pass this argument to
181+
* `grpc::CreateCustomChannel` and create one more more gRPC channels.
182+
*/
183+
grpc::ChannelArguments CreateChannelArguments() const {
184+
grpc::ChannelArguments channel_arguments;
185+
186+
if (!channel_pool_domain().empty()) {
187+
// To get a different channel pool one just needs to set any channel
188+
// parameter to a different value. Newer versions of gRPC include a macro
189+
// for this purpose (GRPC_ARG_CHANNEL_POOL_DOMAIN). As we are compiling
190+
// against older versions in some cases, we use the actual value.
191+
channel_arguments.SetString("grpc.channel_pooling_domain",
192+
channel_pool_domain());
193+
}
194+
channel_arguments.SetUserAgentPrefix(user_agent_prefix());
195+
return channel_arguments;
196+
}
197+
198+
/**
199+
* Configure the connection to use @p cq for all background work.
200+
*
201+
* Connections need to perform background work on behalf of the application.
202+
* Normally they just create a background thread and a `CompletionQueue` for
203+
* this work, but the application may need more fine-grained control of their
204+
* threads. In this case the application can provide the `CompletionQueue` and
205+
* it assumes responsibility for creating one or more threads blocked on
206+
* `CompletionQueue::Run()`.
207+
*/
208+
ConnectionOptions& DisableBackgroundThreads(
209+
google::cloud::CompletionQueue const& cq) {
210+
background_threads_factory_ = [cq] {
211+
return google::cloud::internal::make_unique<
212+
internal::CustomerSuppliedBackgroundThreads>(cq);
213+
};
214+
return *this;
215+
}
216+
217+
using BackgroundThreadsFactory =
218+
std::function<std::unique_ptr<BackgroundThreads>()>;
219+
BackgroundThreadsFactory background_threads_factory() const {
220+
return background_threads_factory_;
221+
}
222+
223+
private:
224+
std::shared_ptr<grpc::ChannelCredentials> credentials_;
225+
std::string endpoint_;
226+
int num_channels_;
227+
std::set<std::string> tracing_components_;
228+
TracingOptions tracing_options_;
229+
std::string channel_pool_domain_;
230+
231+
std::string user_agent_prefix_;
232+
BackgroundThreadsFactory background_threads_factory_;
233+
};
234+
235+
} // namespace GOOGLE_CLOUD_CPP_NS
236+
} // namespace cloud
237+
} // namespace google
238+
239+
#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_CONNECTION_OPTIONS_H

0 commit comments

Comments
 (0)