1 // Copyright 2017 Google Inc.
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
14 #include "google/cloud/bigtable/client_options.h"
15 #include "google/cloud/bigtable/internal/client_options_defaults.h"
16 #include "google/cloud/internal/build_info.h"
17 #include "google/cloud/internal/getenv.h"
18 #include <sstream>
19 #include <thread>
20
21 namespace {
BigtableDefaultCredentials()22 std::shared_ptr<grpc::ChannelCredentials> BigtableDefaultCredentials() {
23 auto emulator = google::cloud::internal::GetEnv("BIGTABLE_EMULATOR_HOST");
24 if (emulator.has_value()) {
25 return grpc::InsecureChannelCredentials();
26 }
27 return grpc::GoogleDefaultCredentials();
28 }
29 } // anonymous namespace
30
31 namespace google {
32 namespace cloud {
33 namespace bigtable {
34 inline namespace BIGTABLE_CLIENT_NS {
35 namespace internal {
36
DefaultDataEndpoint()37 std::string DefaultDataEndpoint() {
38 auto emulator = google::cloud::internal::GetEnv("BIGTABLE_EMULATOR_HOST");
39 if (emulator.has_value()) return *std::move(emulator);
40 auto direct_path =
41 google::cloud::internal::GetEnv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH");
42 if (direct_path.has_value()) {
43 std::istringstream is(*std::move(direct_path));
44 std::string token;
45 while (std::getline(is, token, ',')) {
46 if (token == "bigtable") return "directpath-bigtable.googleapis.com";
47 }
48 }
49 return "bigtable.googleapis.com";
50 }
51
DefaultAdminEndpoint()52 std::string DefaultAdminEndpoint() {
53 auto emulator = google::cloud::internal::GetEnv("BIGTABLE_EMULATOR_HOST");
54 if (emulator.has_value()) return *std::move(emulator);
55 return "bigtableadmin.googleapis.com";
56 }
57
DefaultInstanceAdminEndpoint()58 std::string DefaultInstanceAdminEndpoint() {
59 auto emulator =
60 google::cloud::internal::GetEnv("BIGTABLE_INSTANCE_ADMIN_EMULATOR_HOST");
61 if (emulator.has_value()) return *std::move(emulator);
62 return DefaultAdminEndpoint();
63 }
64
65 } // namespace internal
66
CalculateDefaultConnectionPoolSize()67 inline std::size_t CalculateDefaultConnectionPoolSize() {
68 // For batter resource utilization and greater throughput, it is recommended
69 // to calculate the default pool size based on cores(CPU) available. However,
70 // as per C++11 documentation `std::thread::hardware_concurrency()` cannot be
71 // fully rely upon, it is only a hint and the value can be 0 if it is not
72 // well defined or not computable. Apart from CPU count, multiple channels can
73 // be opened for each CPU to increase throughput.
74 std::size_t cpu_count = std::thread::hardware_concurrency();
75 return (cpu_count > 0) ? cpu_count * BIGTABLE_CLIENT_DEFAULT_CHANNELS_PER_CPU
76 : BIGTABLE_CLIENT_DEFAULT_CONNECTION_POOL_SIZE;
77 }
78
ClientOptions(std::shared_ptr<grpc::ChannelCredentials> creds)79 ClientOptions::ClientOptions(std::shared_ptr<grpc::ChannelCredentials> creds)
80 : credentials_(std::move(creds)),
81 connection_pool_size_(CalculateDefaultConnectionPoolSize()),
82 data_endpoint_("bigtable.googleapis.com"),
83 admin_endpoint_("bigtableadmin.googleapis.com"),
84 instance_admin_endpoint_("bigtableadmin.googleapis.com") {
85 static std::string const kUserAgentPrefix = UserAgentPrefix();
86 channel_arguments_.SetUserAgentPrefix(kUserAgentPrefix);
87 channel_arguments_.SetMaxSendMessageSize(
88 BIGTABLE_CLIENT_DEFAULT_MAX_MESSAGE_LENGTH);
89 channel_arguments_.SetMaxReceiveMessageSize(
90 BIGTABLE_CLIENT_DEFAULT_MAX_MESSAGE_LENGTH);
91 }
92
ClientOptions()93 ClientOptions::ClientOptions() : ClientOptions(BigtableDefaultCredentials()) {
94 data_endpoint_ = internal::DefaultDataEndpoint();
95 admin_endpoint_ = internal::DefaultAdminEndpoint();
96 instance_admin_endpoint_ = internal::DefaultInstanceAdminEndpoint();
97 auto emulator = google::cloud::internal::GetEnv("BIGTABLE_EMULATOR_HOST");
98 if (emulator.has_value()) {
99 data_endpoint_ = *emulator;
100 admin_endpoint_ = *emulator;
101 instance_admin_endpoint_ = *emulator;
102 }
103 auto instance_admin_emulator =
104 google::cloud::internal::GetEnv("BIGTABLE_INSTANCE_ADMIN_EMULATOR_HOST");
105 if (instance_admin_emulator.has_value()) {
106 instance_admin_endpoint_ = *instance_admin_emulator;
107 }
108 }
109
110 // NOLINTNEXTLINE(readability-identifier-naming)
set_connection_pool_size(std::size_t size)111 ClientOptions& ClientOptions::set_connection_pool_size(std::size_t size) {
112 if (size == 0) {
113 connection_pool_size_ = CalculateDefaultConnectionPoolSize();
114 return *this;
115 }
116 connection_pool_size_ = size;
117 return *this;
118 }
119
UserAgentPrefix()120 std::string ClientOptions::UserAgentPrefix() {
121 std::string agent = "gcloud-cpp/" + version_string() + " " +
122 google::cloud::internal::compiler();
123 return agent;
124 }
125
126 } // namespace BIGTABLE_CLIENT_NS
127 } // namespace bigtable
128 } // namespace cloud
129 } // namespace google
130