weighted_target.cc
Go to the documentation of this file.
1 //
2 // Copyright 2018 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
18 
19 #include <stdlib.h>
20 
21 #include <algorithm>
22 #include <cstdint>
23 #include <map>
24 #include <memory>
25 #include <string>
26 #include <utility>
27 #include <vector>
28 
29 #include "absl/memory/memory.h"
30 #include "absl/status/status.h"
31 #include "absl/status/statusor.h"
32 #include "absl/strings/str_cat.h"
33 #include "absl/strings/string_view.h"
34 #include "absl/types/optional.h"
35 
39 #include <grpc/support/log.h>
40 
59 #include "src/core/lib/json/json.h"
62 
63 // IWYU pragma: no_include <type_traits>
64 
65 namespace grpc_core {
66 
67 TraceFlag grpc_lb_weighted_target_trace(false, "weighted_target_lb");
68 
69 namespace {
70 
71 using ::grpc_event_engine::experimental::EventEngine;
73 
74 constexpr char kWeightedTarget[] = "weighted_target_experimental";
75 
76 // How long we keep a child around for after it has been removed from
77 // the config.
78 constexpr Duration kChildRetentionInterval = Duration::Minutes(15);
79 
80 // Config for weighted_target LB policy.
81 class WeightedTargetLbConfig : public LoadBalancingPolicy::Config {
82  public:
83  struct ChildConfig {
85  RefCountedPtr<LoadBalancingPolicy::Config> config;
86  };
87 
88  using TargetMap = std::map<std::string, ChildConfig>;
89 
90  explicit WeightedTargetLbConfig(TargetMap target_map)
91  : target_map_(std::move(target_map)) {}
92 
93  const char* name() const override { return kWeightedTarget; }
94 
95  const TargetMap& target_map() const { return target_map_; }
96 
97  private:
98  TargetMap target_map_;
99 };
100 
101 // weighted_target LB policy.
102 class WeightedTargetLb : public LoadBalancingPolicy {
103  public:
104  explicit WeightedTargetLb(Args args);
105 
106  const char* name() const override { return kWeightedTarget; }
107 
108  void UpdateLocked(UpdateArgs args) override;
109  void ResetBackoffLocked() override;
110 
111  private:
112  // A simple wrapper for ref-counting a picker from the child policy.
113  class ChildPickerWrapper : public RefCounted<ChildPickerWrapper> {
114  public:
115  explicit ChildPickerWrapper(std::unique_ptr<SubchannelPicker> picker)
116  : picker_(std::move(picker)) {}
117  PickResult Pick(PickArgs args) { return picker_->Pick(args); }
118 
119  private:
120  std::unique_ptr<SubchannelPicker> picker_;
121  };
122 
123  // Picks a child using stateless WRR and then delegates to that
124  // child's picker.
125  class WeightedPicker : public SubchannelPicker {
126  public:
127  // Maintains a weighted list of pickers from each child that is in
128  // ready state. The first element in the pair represents the end of a
129  // range proportional to the child's weight. The start of the range
130  // is the previous value in the vector and is 0 for the first element.
131  using PickerList =
132  std::vector<std::pair<uint32_t, RefCountedPtr<ChildPickerWrapper>>>;
133 
134  explicit WeightedPicker(PickerList pickers)
135  : pickers_(std::move(pickers)) {}
136 
137  PickResult Pick(PickArgs args) override;
138 
139  private:
140  PickerList pickers_;
141  };
142 
143  // Each WeightedChild holds a ref to its parent WeightedTargetLb.
144  class WeightedChild : public InternallyRefCounted<WeightedChild> {
145  public:
146  WeightedChild(RefCountedPtr<WeightedTargetLb> weighted_target_policy,
147  const std::string& name);
148  ~WeightedChild() override;
149 
150  void Orphan() override;
151 
152  void UpdateLocked(const WeightedTargetLbConfig::ChildConfig& config,
154  const grpc_channel_args* args);
155  void ResetBackoffLocked();
156  void DeactivateLocked();
157 
158  uint32_t weight() const { return weight_; }
159  grpc_connectivity_state connectivity_state() const {
160  return connectivity_state_;
161  }
162  RefCountedPtr<ChildPickerWrapper> picker_wrapper() const {
163  return picker_wrapper_;
164  }
165 
166  private:
167  class Helper : public ChannelControlHelper {
168  public:
169  explicit Helper(RefCountedPtr<WeightedChild> weighted_child)
170  : weighted_child_(std::move(weighted_child)) {}
171 
172  ~Helper() override { weighted_child_.reset(DEBUG_LOCATION, "Helper"); }
173 
174  RefCountedPtr<SubchannelInterface> CreateSubchannel(
175  ServerAddress address, const grpc_channel_args& args) override;
176  void UpdateState(grpc_connectivity_state state,
177  const absl::Status& status,
178  std::unique_ptr<SubchannelPicker> picker) override;
179  void RequestReresolution() override;
180  absl::string_view GetAuthority() override;
181  void AddTraceEvent(TraceSeverity severity,
182  absl::string_view message) override;
183 
184  private:
185  RefCountedPtr<WeightedChild> weighted_child_;
186  };
187 
188  class DelayedRemovalTimer
189  : public InternallyRefCounted<DelayedRemovalTimer> {
190  public:
191  explicit DelayedRemovalTimer(RefCountedPtr<WeightedChild> weighted_child);
192 
193  void Orphan() override;
194 
195  private:
196  void OnTimerLocked();
197 
198  RefCountedPtr<WeightedChild> weighted_child_;
200  };
201 
202  // Methods for dealing with the child policy.
203  OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
204  const grpc_channel_args* args);
205 
206  void OnConnectivityStateUpdateLocked(
208  std::unique_ptr<SubchannelPicker> picker);
209 
210  // The owning LB policy.
211  RefCountedPtr<WeightedTargetLb> weighted_target_policy_;
212 
214 
216 
217  OrphanablePtr<LoadBalancingPolicy> child_policy_;
218 
219  RefCountedPtr<ChildPickerWrapper> picker_wrapper_;
221 
222  OrphanablePtr<DelayedRemovalTimer> delayed_removal_timer_;
223  };
224 
225  ~WeightedTargetLb() override;
226 
227  void ShutdownLocked() override;
228 
229  void UpdateStateLocked();
230 
231  // Current config from the resolver.
232  RefCountedPtr<WeightedTargetLbConfig> config_;
233 
234  // Internal state.
235  bool shutting_down_ = false;
236  bool update_in_progress_ = false;
237 
238  // Children.
239  std::map<std::string, OrphanablePtr<WeightedChild>> targets_;
240 };
241 
242 //
243 // WeightedTargetLb::WeightedPicker
244 //
245 
246 WeightedTargetLb::PickResult WeightedTargetLb::WeightedPicker::Pick(
247  PickArgs args) {
248  // Generate a random number in [0, total weight).
249  const uint32_t key = rand() % pickers_[pickers_.size() - 1].first;
250  // Find the index in pickers_ corresponding to key.
251  size_t mid = 0;
252  size_t start_index = 0;
253  size_t end_index = pickers_.size() - 1;
254  size_t index = 0;
255  while (end_index > start_index) {
256  mid = (start_index + end_index) / 2;
257  if (pickers_[mid].first > key) {
258  end_index = mid;
259  } else if (pickers_[mid].first < key) {
260  start_index = mid + 1;
261  } else {
262  index = mid + 1;
263  break;
264  }
265  }
266  if (index == 0) index = start_index;
268  // Delegate to the child picker.
269  return pickers_[index].second->Pick(args);
270 }
271 
272 //
273 // WeightedTargetLb
274 //
275 
276 WeightedTargetLb::WeightedTargetLb(Args args)
277  : LoadBalancingPolicy(std::move(args)) {
279  gpr_log(GPR_INFO, "[weighted_target_lb %p] created", this);
280  }
281 }
282 
283 WeightedTargetLb::~WeightedTargetLb() {
286  "[weighted_target_lb %p] destroying weighted_target LB policy",
287  this);
288  }
289 }
290 
291 void WeightedTargetLb::ShutdownLocked() {
293  gpr_log(GPR_INFO, "[weighted_target_lb %p] shutting down", this);
294  }
295  shutting_down_ = true;
296  targets_.clear();
297 }
298 
299 void WeightedTargetLb::ResetBackoffLocked() {
300  for (auto& p : targets_) p.second->ResetBackoffLocked();
301 }
302 
303 void WeightedTargetLb::UpdateLocked(UpdateArgs args) {
304  if (shutting_down_) return;
306  gpr_log(GPR_INFO, "[weighted_target_lb %p] Received update", this);
307  }
308  update_in_progress_ = true;
309  // Update config.
310  config_ = std::move(args.config);
311  // Deactivate the targets not in the new config.
312  for (const auto& p : targets_) {
313  const std::string& name = p.first;
314  WeightedChild* child = p.second.get();
315  if (config_->target_map().find(name) == config_->target_map().end()) {
316  child->DeactivateLocked();
317  }
318  }
319  // Update all children.
321  MakeHierarchicalAddressMap(args.addresses);
322  for (const auto& p : config_->target_map()) {
323  const std::string& name = p.first;
324  const WeightedTargetLbConfig::ChildConfig& config = p.second;
325  auto& target = targets_[name];
326  // Create child if it does not already exist.
327  if (target == nullptr) {
328  target = MakeOrphanable<WeightedChild>(
329  Ref(DEBUG_LOCATION, "WeightedChild"), name);
330  }
332  if (address_map.ok()) {
333  addresses = std::move((*address_map)[name]);
334  } else {
335  addresses = address_map.status();
336  }
337  target->UpdateLocked(config, std::move(addresses), args.args);
338  }
339  update_in_progress_ = false;
340  if (config_->target_map().empty()) {
342  "no children in weighted_target policy: ", args.resolution_note));
343  channel_control_helper()->UpdateState(
345  absl::make_unique<TransientFailurePicker>(status));
346  return;
347  }
348  UpdateStateLocked();
349 }
350 
351 void WeightedTargetLb::UpdateStateLocked() {
352  // If we're in the process of propagating an update from our parent to
353  // our children, ignore any updates that come from the children. We
354  // will instead return a new picker once the update has been seen by
355  // all children. This avoids unnecessary picker churn while an update
356  // is being propagated to our children.
357  if (update_in_progress_) return;
360  "[weighted_target_lb %p] scanning children to determine "
361  "connectivity state",
362  this);
363  }
364  // Construct lists of child pickers with associated weights, one for
365  // children that are in state READY and another for children that are
366  // in state TRANSIENT_FAILURE. Each child is represented by a portion of
367  // the range proportional to its weight, such that the total range is the
368  // sum of the weights of all children.
369  WeightedPicker::PickerList ready_picker_list;
370  uint32_t ready_end = 0;
371  WeightedPicker::PickerList tf_picker_list;
372  uint32_t tf_end = 0;
373  // Also count the number of children in CONNECTING and IDLE, to determine
374  // the aggregated state.
375  size_t num_connecting = 0;
376  size_t num_idle = 0;
377  for (const auto& p : targets_) {
378  const std::string& child_name = p.first;
379  const WeightedChild* child = p.second.get();
380  // Skip the targets that are not in the latest update.
381  if (config_->target_map().find(child_name) == config_->target_map().end()) {
382  continue;
383  }
386  "[weighted_target_lb %p] child=%s state=%s weight=%d picker=%p",
387  this, child_name.c_str(),
388  ConnectivityStateName(child->connectivity_state()),
389  child->weight(), child->picker_wrapper().get());
390  }
391  switch (child->connectivity_state()) {
392  case GRPC_CHANNEL_READY: {
393  GPR_ASSERT(child->weight() > 0);
394  ready_end += child->weight();
395  ready_picker_list.emplace_back(ready_end, child->picker_wrapper());
396  break;
397  }
399  ++num_connecting;
400  break;
401  }
402  case GRPC_CHANNEL_IDLE: {
403  ++num_idle;
404  break;
405  }
407  GPR_ASSERT(child->weight() > 0);
408  tf_end += child->weight();
409  tf_picker_list.emplace_back(tf_end, child->picker_wrapper());
410  break;
411  }
412  default:
413  GPR_UNREACHABLE_CODE(return );
414  }
415  }
416  // Determine aggregated connectivity state.
417  grpc_connectivity_state connectivity_state;
418  if (!ready_picker_list.empty()) {
419  connectivity_state = GRPC_CHANNEL_READY;
420  } else if (num_connecting > 0) {
421  connectivity_state = GRPC_CHANNEL_CONNECTING;
422  } else if (num_idle > 0) {
423  connectivity_state = GRPC_CHANNEL_IDLE;
424  } else {
425  connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
426  }
428  gpr_log(GPR_INFO, "[weighted_target_lb %p] connectivity changed to %s",
429  this, ConnectivityStateName(connectivity_state));
430  }
431  std::unique_ptr<SubchannelPicker> picker;
433  switch (connectivity_state) {
434  case GRPC_CHANNEL_READY:
435  picker = absl::make_unique<WeightedPicker>(std::move(ready_picker_list));
436  break;
438  case GRPC_CHANNEL_IDLE:
439  picker =
440  absl::make_unique<QueuePicker>(Ref(DEBUG_LOCATION, "QueuePicker"));
441  break;
442  default:
443  picker = absl::make_unique<WeightedPicker>(std::move(tf_picker_list));
444  }
445  channel_control_helper()->UpdateState(connectivity_state, status,
446  std::move(picker));
447 }
448 
449 //
450 // WeightedTargetLb::WeightedChild::DelayedRemovalTimer
451 //
452 
453 WeightedTargetLb::WeightedChild::DelayedRemovalTimer::DelayedRemovalTimer(
454  RefCountedPtr<WeightedTargetLb::WeightedChild> weighted_child)
455  : weighted_child_(std::move(weighted_child)) {
457  kChildRetentionInterval, [self = Ref()]() mutable {
458  self->weighted_child_->weighted_target_policy_->work_serializer()->Run(
459  [self = std::move(self)] { self->OnTimerLocked(); },
461  });
462 }
463 
464 void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::Orphan() {
465  if (timer_handle_.has_value()) {
468  "[weighted_target_lb %p] WeightedChild %p %s: cancelling "
469  "delayed removal timer",
470  weighted_child_->weighted_target_policy_.get(),
471  weighted_child_.get(), weighted_child_->name_.c_str());
472  }
474  }
475  Unref();
476 }
477 
478 void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::OnTimerLocked() {
481  weighted_child_->weighted_target_policy_->targets_.erase(
482  weighted_child_->name_);
483 }
484 
485 //
486 // WeightedTargetLb::WeightedChild
487 //
488 
489 WeightedTargetLb::WeightedChild::WeightedChild(
490  RefCountedPtr<WeightedTargetLb> weighted_target_policy,
491  const std::string& name)
492  : weighted_target_policy_(std::move(weighted_target_policy)), name_(name) {
494  gpr_log(GPR_INFO, "[weighted_target_lb %p] created WeightedChild %p for %s",
495  weighted_target_policy_.get(), this, name_.c_str());
496  }
497 }
498 
499 WeightedTargetLb::WeightedChild::~WeightedChild() {
502  "[weighted_target_lb %p] WeightedChild %p %s: destroying child",
503  weighted_target_policy_.get(), this, name_.c_str());
504  }
505  weighted_target_policy_.reset(DEBUG_LOCATION, "WeightedChild");
506 }
507 
508 void WeightedTargetLb::WeightedChild::Orphan() {
511  "[weighted_target_lb %p] WeightedChild %p %s: shutting down child",
512  weighted_target_policy_.get(), this, name_.c_str());
513  }
514  // Remove the child policy's interested_parties pollset_set from the
515  // xDS policy.
517  child_policy_->interested_parties(),
518  weighted_target_policy_->interested_parties());
519  child_policy_.reset();
520  // Drop our ref to the child's picker, in case it's holding a ref to
521  // the child.
522  picker_wrapper_.reset();
523  delayed_removal_timer_.reset();
524  Unref();
525 }
526 
527 OrphanablePtr<LoadBalancingPolicy>
528 WeightedTargetLb::WeightedChild::CreateChildPolicyLocked(
529  const grpc_channel_args* args) {
530  LoadBalancingPolicy::Args lb_policy_args;
531  lb_policy_args.work_serializer = weighted_target_policy_->work_serializer();
532  lb_policy_args.args = args;
533  lb_policy_args.channel_control_helper =
534  absl::make_unique<Helper>(this->Ref(DEBUG_LOCATION, "Helper"));
535  OrphanablePtr<LoadBalancingPolicy> lb_policy =
536  MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args),
540  "[weighted_target_lb %p] WeightedChild %p %s: Created new child "
541  "policy handler %p",
542  weighted_target_policy_.get(), this, name_.c_str(),
543  lb_policy.get());
544  }
545  // Add the xDS's interested_parties pollset_set to that of the newly created
546  // child policy. This will make the child policy progress upon activity on
547  // xDS LB, which in turn is tied to the application's call.
549  lb_policy->interested_parties(),
550  weighted_target_policy_->interested_parties());
551  return lb_policy;
552 }
553 
554 void WeightedTargetLb::WeightedChild::UpdateLocked(
555  const WeightedTargetLbConfig::ChildConfig& config,
557  const grpc_channel_args* args) {
558  if (weighted_target_policy_->shutting_down_) return;
559  // Update child weight.
560  weight_ = config.weight;
561  // Reactivate if needed.
562  if (delayed_removal_timer_ != nullptr) {
565  "[weighted_target_lb %p] WeightedChild %p %s: reactivating",
566  weighted_target_policy_.get(), this, name_.c_str());
567  }
568  delayed_removal_timer_.reset();
569  }
570  // Create child policy if needed.
571  if (child_policy_ == nullptr) {
572  child_policy_ = CreateChildPolicyLocked(args);
573  }
574  // Construct update args.
575  UpdateArgs update_args;
576  update_args.config = config.config;
577  update_args.addresses = std::move(addresses);
578  update_args.args = grpc_channel_args_copy(args);
579  // Update the policy.
582  "[weighted_target_lb %p] WeightedChild %p %s: Updating child "
583  "policy handler %p",
584  weighted_target_policy_.get(), this, name_.c_str(),
585  child_policy_.get());
586  }
587  child_policy_->UpdateLocked(std::move(update_args));
588 }
589 
590 void WeightedTargetLb::WeightedChild::ResetBackoffLocked() {
591  child_policy_->ResetBackoffLocked();
592 }
593 
594 void WeightedTargetLb::WeightedChild::OnConnectivityStateUpdateLocked(
596  std::unique_ptr<SubchannelPicker> picker) {
597  // Cache the picker in the WeightedChild.
598  picker_wrapper_ = MakeRefCounted<ChildPickerWrapper>(std::move(picker));
601  "[weighted_target_lb %p] WeightedChild %p %s: connectivity "
602  "state update: state=%s (%s) picker_wrapper=%p",
603  weighted_target_policy_.get(), this, name_.c_str(),
605  picker_wrapper_.get());
606  }
607  // If the child reports IDLE, immediately tell it to exit idle.
608  if (state == GRPC_CHANNEL_IDLE) child_policy_->ExitIdleLocked();
609  // Decide what state to report for aggregation purposes.
610  // If the last recorded state was TRANSIENT_FAILURE and the new state
611  // is something other than READY, don't change the state.
615  }
616  // Notify the LB policy.
617  weighted_target_policy_->UpdateStateLocked();
618 }
619 
620 void WeightedTargetLb::WeightedChild::DeactivateLocked() {
621  // If already deactivated, don't do that again.
622  if (weight_ == 0) return;
625  "[weighted_target_lb %p] WeightedChild %p %s: deactivating",
626  weighted_target_policy_.get(), this, name_.c_str());
627  }
628  // Set the child weight to 0 so that future picker won't contain this child.
629  weight_ = 0;
630  // Start a timer to delete the child.
631  delayed_removal_timer_ = MakeOrphanable<DelayedRemovalTimer>(
632  Ref(DEBUG_LOCATION, "DelayedRemovalTimer"));
633 }
634 
635 //
636 // WeightedTargetLb::WeightedChild::Helper
637 //
638 
639 RefCountedPtr<SubchannelInterface>
640 WeightedTargetLb::WeightedChild::Helper::CreateSubchannel(
641  ServerAddress address, const grpc_channel_args& args) {
642  if (weighted_child_->weighted_target_policy_->shutting_down_) return nullptr;
643  return weighted_child_->weighted_target_policy_->channel_control_helper()
644  ->CreateSubchannel(std::move(address), args);
645 }
646 
647 void WeightedTargetLb::WeightedChild::Helper::UpdateState(
649  std::unique_ptr<SubchannelPicker> picker) {
650  if (weighted_child_->weighted_target_policy_->shutting_down_) return;
651  weighted_child_->OnConnectivityStateUpdateLocked(state, status,
652  std::move(picker));
653 }
654 
655 void WeightedTargetLb::WeightedChild::Helper::RequestReresolution() {
656  if (weighted_child_->weighted_target_policy_->shutting_down_) return;
657  weighted_child_->weighted_target_policy_->channel_control_helper()
658  ->RequestReresolution();
659 }
660 
661 absl::string_view WeightedTargetLb::WeightedChild::Helper::GetAuthority() {
662  return weighted_child_->weighted_target_policy_->channel_control_helper()
663  ->GetAuthority();
664 }
665 
666 void WeightedTargetLb::WeightedChild::Helper::AddTraceEvent(
667  TraceSeverity severity, absl::string_view message) {
668  if (weighted_child_->weighted_target_policy_->shutting_down_) return;
669  weighted_child_->weighted_target_policy_->channel_control_helper()
670  ->AddTraceEvent(severity, message);
671 }
672 
673 //
674 // factory
675 //
676 
677 class WeightedTargetLbFactory : public LoadBalancingPolicyFactory {
678  public:
679  OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
680  LoadBalancingPolicy::Args args) const override {
681  return MakeOrphanable<WeightedTargetLb>(std::move(args));
682  }
683 
684  const char* name() const override { return kWeightedTarget; }
685 
686  RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
687  const Json& json, grpc_error_handle* error) const override {
689  if (json.type() == Json::Type::JSON_NULL) {
690  // weighted_target was mentioned as a policy in the deprecated
691  // loadBalancingPolicy field or in the client API.
693  "field:loadBalancingPolicy error:weighted_target policy requires "
694  "configuration. Please use loadBalancingConfig field of service "
695  "config instead.");
696  return nullptr;
697  }
698  std::vector<grpc_error_handle> error_list;
699  // Weight map.
700  WeightedTargetLbConfig::TargetMap target_map;
701  auto it = json.object_value().find("targets");
702  if (it == json.object_value().end()) {
703  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
704  "field:targets error:required field not present"));
705  } else if (it->second.type() != Json::Type::OBJECT) {
706  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
707  "field:targets error:type should be object"));
708  } else {
709  for (const auto& p : it->second.object_value()) {
710  WeightedTargetLbConfig::ChildConfig child_config;
711  std::vector<grpc_error_handle> child_errors =
712  ParseChildConfig(p.second, &child_config);
713  if (!child_errors.empty()) {
715  absl::StrCat("field:targets key:", p.first), &child_errors));
716  } else {
717  target_map[p.first] = std::move(child_config);
718  }
719  }
720  }
721  if (!error_list.empty()) {
723  "weighted_target_experimental LB policy config", &error_list);
724  return nullptr;
725  }
726  return MakeRefCounted<WeightedTargetLbConfig>(std::move(target_map));
727  }
728 
729  private:
730  static std::vector<grpc_error_handle> ParseChildConfig(
731  const Json& json, WeightedTargetLbConfig::ChildConfig* child_config) {
732  std::vector<grpc_error_handle> error_list;
733  if (json.type() != Json::Type::OBJECT) {
734  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
735  "value should be of type object"));
736  return error_list;
737  }
738  // Weight.
739  auto it = json.object_value().find("weight");
740  if (it == json.object_value().end()) {
741  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
742  "required field \"weight\" not specified"));
743  } else if (it->second.type() != Json::Type::NUMBER) {
744  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
745  "field:weight error:must be of type number"));
746  } else {
747  int weight = gpr_parse_nonnegative_int(it->second.string_value().c_str());
748  if (weight == -1) {
749  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
750  "field:weight error:unparseable value"));
751  } else if (weight == 0) {
752  error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
753  "field:weight error:value must be greater than zero"));
754  } else {
755  child_config->weight = weight;
756  }
757  }
758  // Child policy.
759  it = json.object_value().find("childPolicy");
760  if (it != json.object_value().end()) {
762  child_config->config =
763  LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(it->second,
764  &parse_error);
765  if (child_config->config == nullptr) {
767  std::vector<grpc_error_handle> child_errors;
768  child_errors.push_back(parse_error);
769  error_list.push_back(
770  GRPC_ERROR_CREATE_FROM_VECTOR("field:childPolicy", &child_errors));
771  }
772  }
773  return error_list;
774  }
775 };
776 
777 } // namespace
778 
779 } // namespace grpc_core
780 
781 //
782 // Plugin registration
783 //
784 
788  absl::make_unique<grpc_core::WeightedTargetLbFactory>());
789 }
790 
config
RefCountedPtr< LoadBalancingPolicy::Config > config
Definition: weighted_target.cc:85
trace.h
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
GRPC_CHANNEL_READY
@ GRPC_CHANNEL_READY
Definition: include/grpc/impl/codegen/connectivity_state.h:36
address_filtering.h
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
orphanable.h
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
log.h
grpc_lb_policy_weighted_target_init
void grpc_lb_policy_weighted_target_init()
Definition: weighted_target.cc:785
bloat_diff.severity
def severity
Definition: bloat_diff.py:143
absl::Status::ToString
std::string ToString(StatusToStringMode mode=StatusToStringMode::kDefault) const
Definition: third_party/abseil-cpp/absl/status/status.h:821
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
connectivity_state.h
GPR_DEBUG_ASSERT
#define GPR_DEBUG_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:103
grpc_core
Definition: call_metric_recorder.h:31
event_engine.h
string.h
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
lb_policy.h
grpc_event_engine::experimental::EventEngine::Cancel
virtual bool Cancel(TaskHandle handle)=0
lb_policy_factory.h
GRPC_CHANNEL_TRANSIENT_FAILURE
@ GRPC_CHANNEL_TRANSIENT_FAILURE
Definition: include/grpc/impl/codegen/connectivity_state.h:38
status
absl::Status status
Definition: rls.cc:251
update_in_progress_
bool update_in_progress_
Definition: weighted_target.cc:236
setup.name
name
Definition: setup.py:542
xds_manager.p
p
Definition: xds_manager.py:60
grpc_event_engine::experimental::EventEngine::RunAfter
virtual TaskHandle RunAfter(Duration when, Closure *closure)=0
grpc_pollset_set_del_pollset_set
void grpc_pollset_set_del_pollset_set(grpc_pollset_set *bag, grpc_pollset_set *item)
Definition: pollset_set.cc:52
grpc_channel_args
Definition: grpc_types.h:132
GRPC_TRACE_FLAG_ENABLED
#define GRPC_TRACE_FLAG_ENABLED(f)
Definition: debug/trace.h:114
subchannel_interface.h
grpc_core::MakeHierarchicalAddressMap
absl::StatusOr< HierarchicalAddressMap > MakeHierarchicalAddressMap(const absl::StatusOr< ServerAddressList > &addresses)
Definition: address_filtering.cc:76
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
grpc_connectivity_state
grpc_connectivity_state
Definition: include/grpc/impl/codegen/connectivity_state.h:30
GRPC_ERROR_CREATE_FROM_VECTOR
#define GRPC_ERROR_CREATE_FROM_VECTOR(desc, error_list)
Definition: error.h:314
grpc_types.h
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
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
weighted_target_policy_
RefCountedPtr< WeightedTargetLb > weighted_target_policy_
Definition: weighted_target.cc:211
hpack_encoder_fixtures::Args
Args({0, 16384})
connectivity_state_
grpc_connectivity_state connectivity_state_
Definition: weighted_target.cc:220
absl::optional::has_value
constexpr bool has_value() const noexcept
Definition: abseil-cpp/absl/types/optional.h:461
Json
JSON (JavaScript Object Notation).
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:227
picker_
std::unique_ptr< SubchannelPicker > picker_
Definition: weighted_target.cc:120
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
work_serializer.h
targets_
std::map< std::string, OrphanablePtr< WeightedChild > > targets_
Definition: weighted_target.cc:239
connectivity_state.h
timer_handle_
absl::optional< EventEngine::TaskHandle > timer_handle_
Definition: weighted_target.cc:199
absl::optional< EventEngine::TaskHandle >
pollset_set.h
GRPC_CHANNEL_IDLE
@ GRPC_CHANNEL_IDLE
Definition: include/grpc/impl/codegen/connectivity_state.h:32
server_address.h
time.h
grpc_channel_args_copy
grpc_channel_args * grpc_channel_args_copy(const grpc_channel_args *src)
Definition: channel_args.cc:285
googletest-filter-unittest.child
child
Definition: bloaty/third_party/googletest/googletest/test/googletest-filter-unittest.py:62
error.h
json.h
GPR_UNREACHABLE_CODE
#define GPR_UNREACHABLE_CODE(STATEMENT)
Definition: impl/codegen/port_platform.h:652
weight
uint32_t weight
Definition: weighted_target.cc:84
GRPC_ERROR_CREATE_FROM_STATIC_STRING
#define GRPC_ERROR_CREATE_FROM_STATIC_STRING(desc)
Definition: error.h:291
GRPC_CHANNEL_CONNECTING
@ GRPC_CHANNEL_CONNECTING
Definition: include/grpc/impl/codegen/connectivity_state.h:34
child_policy_handler.h
pickers_
PickerList pickers_
Definition: weighted_target.cc:140
child_policy_
OrphanablePtr< LoadBalancingPolicy > child_policy_
Definition: weighted_target.cc:217
absl::StatusOr::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: abseil-cpp/absl/status/statusor.h:491
grpc_core::ConnectivityStateName
const char * ConnectivityStateName(grpc_connectivity_state state)
Definition: connectivity_state.cc:38
debug_location.h
key
const char * key
Definition: hpack_parser_table.cc:164
grpc_lb_policy_weighted_target_shutdown
void grpc_lb_policy_weighted_target_shutdown()
Definition: weighted_target.cc:791
shutting_down_
bool shutting_down_
Definition: weighted_target.cc:235
lb_policy_registry.h
ref_counted.h
absl::optional::reset
ABSL_ATTRIBUTE_REINITIALIZES void reset() noexcept
Definition: abseil-cpp/absl/types/optional.h:342
absl::Status
Definition: third_party/abseil-cpp/absl/status/status.h:424
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc_pollset_set_add_pollset_set
void grpc_pollset_set_add_pollset_set(grpc_pollset_set *bag, grpc_pollset_set *item)
Definition: pollset_set.cc:47
first
StrT first
Definition: cxa_demangle.cpp:4884
grpc_event_engine::experimental::GetDefaultEventEngine
EventEngine * GetDefaultEventEngine()
Definition: event_engine.cc:47
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
grpc_core::grpc_lb_weighted_target_trace
TraceFlag grpc_lb_weighted_target_trace(false, "weighted_target_lb")
GRPC_ERROR_CREATE_FROM_VECTOR_AND_CPP_STRING
#define GRPC_ERROR_CREATE_FROM_VECTOR_AND_CPP_STRING(desc, error_list)
Definition: error.h:317
absl::UnavailableError
Status UnavailableError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:375
ref_counted_ptr.h
config_s
Definition: bloaty/third_party/zlib/deflate.c:120
delayed_removal_timer_
OrphanablePtr< DelayedRemovalTimer > delayed_removal_timer_
Definition: weighted_target.cc:222
picker_wrapper_
RefCountedPtr< ChildPickerWrapper > picker_wrapper_
Definition: weighted_target.cc:219
channel_args.h
check_redundant_namespace_qualifiers.Config
Config
Definition: check_redundant_namespace_qualifiers.py:142
target_map_
TargetMap target_map_
Definition: weighted_target.cc:98
gpr_parse_nonnegative_int
int gpr_parse_nonnegative_int(const char *value)
Definition: string.cc:218
Duration
Definition: bloaty/third_party/protobuf/src/google/protobuf/duration.pb.h:69
absl::StatusOr< ServerAddressList >
googletest-break-on-failure-unittest.Run
def Run(command)
Definition: bloaty/third_party/googletest/googletest/test/googletest-break-on-failure-unittest.py:76
weighted_child_
RefCountedPtr< WeightedChild > weighted_child_
Definition: weighted_target.cc:185
grpc_error
Definition: error_internal.h:42
event_engine_factory.h
testing::Ref
internal::RefMatcher< T & > Ref(T &x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8628
config_
RefCountedPtr< WeightedTargetLbConfig > config_
Definition: weighted_target.cc:232
name_
const std::string name_
Definition: weighted_target.cc:213
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179
state
static struct rpc_state state
Definition: bad_server_response_test.cc:87
absl::StatusOr::status
const Status & status() const &
Definition: abseil-cpp/absl/status/statusor.h:678
weight_
uint32_t weight_
Definition: weighted_target.cc:215
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
parse_error
@ parse_error
Definition: pem_info.c:88
grpc_core::Duration::Minutes
static constexpr Duration Minutes(int64_t minutes)
Definition: src/core/lib/gprpp/time.h:147
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:53