lb_policy_registry.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include <string.h>
24 
25 #include <algorithm>
26 #include <map>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 
31 #include "absl/strings/str_cat.h"
32 #include "absl/strings/str_format.h"
33 #include "absl/strings/str_join.h"
34 #include "absl/strings/string_view.h"
35 
36 #include <grpc/support/log.h>
37 
38 namespace grpc_core {
39 
40 namespace {
41 
42 class RegistryState {
43  public:
44  RegistryState() {}
45 
46  void RegisterLoadBalancingPolicyFactory(
47  std::unique_ptr<LoadBalancingPolicyFactory> factory) {
48  gpr_log(GPR_DEBUG, "registering LB policy factory for \"%s\"",
49  factory->name());
50  for (size_t i = 0; i < factories_.size(); ++i) {
51  GPR_ASSERT(strcmp(factories_[i]->name(), factory->name()) != 0);
52  }
53  factories_.push_back(std::move(factory));
54  }
55 
56  LoadBalancingPolicyFactory* GetLoadBalancingPolicyFactory(
57  const char* name) const {
58  for (size_t i = 0; i < factories_.size(); ++i) {
59  if (strcmp(name, factories_[i]->name()) == 0) {
60  return factories_[i].get();
61  }
62  }
63  return nullptr;
64  }
65 
66  private:
67  std::vector<std::unique_ptr<LoadBalancingPolicyFactory>> factories_;
68 };
69 
70 RegistryState* g_state = nullptr;
71 
72 } // namespace
73 
74 //
75 // LoadBalancingPolicyRegistry::Builder
76 //
77 
79  if (g_state == nullptr) g_state = new RegistryState();
80 }
81 
83  delete g_state;
84  g_state = nullptr;
85 }
86 
88  std::unique_ptr<LoadBalancingPolicyFactory> factory) {
89  InitRegistry();
90  g_state->RegisterLoadBalancingPolicyFactory(std::move(factory));
91 }
92 
93 //
94 // LoadBalancingPolicyRegistry
95 //
96 
99  const char* name, LoadBalancingPolicy::Args args) {
100  GPR_ASSERT(g_state != nullptr);
101  // Find factory.
102  LoadBalancingPolicyFactory* factory =
103  g_state->GetLoadBalancingPolicyFactory(name);
104  if (factory == nullptr) return nullptr; // Specified name not found.
105  // Create policy via factory.
106  return factory->CreateLoadBalancingPolicy(std::move(args));
107 }
108 
110  const char* name, bool* requires_config) {
111  GPR_ASSERT(g_state != nullptr);
112  auto* factory = g_state->GetLoadBalancingPolicyFactory(name);
113  if (factory == nullptr) {
114  return false;
115  }
116  if (requires_config != nullptr) {
118  // Check if the load balancing policy allows an empty config
119  *requires_config =
120  factory->ParseLoadBalancingConfig(Json(), &error) == nullptr;
122  }
123  return true;
124 }
125 
126 namespace {
127 
128 // Returns the JSON node of policy (with both policy name and config content)
129 // given the JSON node of a LoadBalancingConfig array.
130 grpc_error_handle ParseLoadBalancingConfigHelper(
131  const Json& lb_config_array, Json::Object::const_iterator* result) {
132  if (lb_config_array.type() != Json::Type::ARRAY) {
133  return GRPC_ERROR_CREATE_FROM_STATIC_STRING("type should be array");
134  }
135  // Find the first LB policy that this client supports.
136  std::vector<absl::string_view> policies_tried;
137  for (const Json& lb_config : lb_config_array.array_value()) {
138  if (lb_config.type() != Json::Type::OBJECT) {
140  "child entry should be of type object");
141  }
142  if (lb_config.object_value().empty()) {
144  "no policy found in child entry");
145  }
146  if (lb_config.object_value().size() > 1) {
147  return GRPC_ERROR_CREATE_FROM_STATIC_STRING("oneOf violation");
148  }
149  auto it = lb_config.object_value().begin();
150  if (it->second.type() != Json::Type::OBJECT) {
152  "child entry should be of type object");
153  }
154  // If we support this policy, then select it.
156  it->first.c_str(), nullptr)) {
157  *result = it;
158  return GRPC_ERROR_NONE;
159  }
160  policies_tried.push_back(it->first);
161  }
163  "No known policies in list: ", absl::StrJoin(policies_tried, " ")));
164 }
165 
166 } // namespace
167 
168 RefCountedPtr<LoadBalancingPolicy::Config>
170  const Json& json, grpc_error_handle* error) {
172  GPR_ASSERT(g_state != nullptr);
173  Json::Object::const_iterator policy;
174  *error = ParseLoadBalancingConfigHelper(json, &policy);
175  if (!GRPC_ERROR_IS_NONE(*error)) {
176  return nullptr;
177  }
178  // Find factory.
179  LoadBalancingPolicyFactory* factory =
180  g_state->GetLoadBalancingPolicyFactory(policy->first.c_str());
181  if (factory == nullptr) {
183  absl::StrFormat("Factory not found for policy \"%s\"", policy->first));
184  return nullptr;
185  }
186  // Parse load balancing config via factory.
187  return factory->ParseLoadBalancingConfig(policy->second, error);
188 }
189 
190 } // namespace grpc_core
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
cleanup.Json
Json
Definition: cleanup.py:49
regen-readme.it
it
Definition: regen-readme.py:15
grpc_core::LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory
static void RegisterLoadBalancingPolicyFactory(std::unique_ptr< LoadBalancingPolicyFactory > factory)
Definition: lb_policy_registry.cc:87
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
grpc_core::Json::type
Type type() const
Definition: src/core/lib/json/json.h:174
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
GPR_DEBUG_ASSERT
#define GPR_DEBUG_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:103
grpc_core::Json::Type::OBJECT
@ OBJECT
grpc_core::LoadBalancingPolicyFactory::CreateLoadBalancingPolicy
virtual OrphanablePtr< LoadBalancingPolicy > CreateLoadBalancingPolicy(LoadBalancingPolicy::Args) const =0
Returns a new LB policy instance.
grpc_core
Definition: call_metric_recorder.h:31
string.h
error
grpc_error_handle error
Definition: retry_filter.cc:499
setup.name
name
Definition: setup.py:542
grpc_core::LoadBalancingPolicyFactory
Definition: lb_policy_factory.h:32
grpc_core::Json::array_value
const Array & array_value() const
Definition: src/core/lib/json/json.h:179
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
absl::StrJoin
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep, Formatter &&fmt)
Definition: abseil-cpp/absl/strings/str_join.h:239
Json
JSON (JavaScript Object Notation).
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:227
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc_core::Json::Type::ARRAY
@ ARRAY
grpc_core::LoadBalancingPolicy::Args
Args used to instantiate an LB policy.
Definition: lb_policy.h:343
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy
static OrphanablePtr< LoadBalancingPolicy > CreateLoadBalancingPolicy(const char *name, LoadBalancingPolicy::Args args)
Creates an LB policy of the type specified by name.
Definition: lb_policy_registry.cc:98
grpc_core::LoadBalancingPolicyRegistry::ParseLoadBalancingConfig
static RefCountedPtr< LoadBalancingPolicy::Config > ParseLoadBalancingConfig(const Json &json, grpc_error_handle *error)
Definition: lb_policy_registry.cc:169
lb_policy_registry.h
GRPC_ERROR_CREATE_FROM_CPP_STRING
#define GRPC_ERROR_CREATE_FROM_CPP_STRING(desc)
Definition: error.h:297
grpc_core::OrphanablePtr
std::unique_ptr< T, Deleter > OrphanablePtr
Definition: orphanable.h:64
grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry
static void InitRegistry()
Global initialization and shutdown hooks.
Definition: lb_policy_registry.cc:78
GRPC_ERROR_UNREF
#define GRPC_ERROR_UNREF(err)
Definition: error.h:262
g_state
static struct test_state g_state
Definition: invalid_call_argument_test.cc:55
factories_
std::vector< std::unique_ptr< LoadBalancingPolicyFactory > > factories_
Definition: lb_policy_registry.cc:67
GPR_DEBUG
#define GPR_DEBUG
Definition: include/grpc/impl/codegen/log.h:55
grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists
static bool LoadBalancingPolicyExists(const char *name, bool *requires_config)
Definition: lb_policy_registry.cc:109
grpc_error
Definition: error_internal.h:42
grpc_core::LoadBalancingPolicyRegistry::Builder::ShutdownRegistry
static void ShutdownRegistry()
Definition: lb_policy_registry.cc:82
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
port_platform.h
grpc_core::LoadBalancingPolicyFactory::ParseLoadBalancingConfig
virtual RefCountedPtr< LoadBalancingPolicy::Config > ParseLoadBalancingConfig(const Json &json, grpc_error_handle *error) const =0


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:15