LCOV - code coverage report
Current view: top level - source/extensions/load_balancing_policies/subset - subset_lb.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 141 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 42 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <algorithm>
       4             : #include <bitset>
       5             : #include <cstdint>
       6             : #include <functional>
       7             : #include <map>
       8             : #include <memory>
       9             : #include <string>
      10             : 
      11             : #include "envoy/common/optref.h"
      12             : #include "envoy/config/cluster/v3/cluster.pb.h"
      13             : #include "envoy/extensions/load_balancing_policies/subset/v3/subset.pb.h"
      14             : #include "envoy/extensions/load_balancing_policies/subset/v3/subset.pb.validate.h"
      15             : #include "envoy/runtime/runtime.h"
      16             : #include "envoy/stats/scope.h"
      17             : #include "envoy/stream_info/stream_info.h"
      18             : #include "envoy/upstream/load_balancer.h"
      19             : 
      20             : #include "source/common/common/macros.h"
      21             : #include "source/common/protobuf/protobuf.h"
      22             : #include "source/common/protobuf/utility.h"
      23             : #include "source/common/upstream/load_balancer_impl.h"
      24             : #include "source/common/upstream/upstream_impl.h"
      25             : 
      26             : #include "absl/container/node_hash_map.h"
      27             : #include "absl/types/optional.h"
      28             : 
      29             : namespace Envoy {
      30             : namespace Upstream {
      31             : 
      32             : class ChildLoadBalancerCreator {
      33             : public:
      34           0 :   virtual ~ChildLoadBalancerCreator() = default;
      35             : 
      36             :   virtual std::pair<ThreadAwareLoadBalancerPtr, LoadBalancerPtr>
      37             :   createLoadBalancer(const PrioritySet& child_priority_set, const PrioritySet* local_priority_set,
      38             :                      ClusterLbStats& stats, Stats::Scope& scope, Runtime::Loader& runtime,
      39             :                      Random::RandomGenerator& random, TimeSource& time_source) PURE;
      40             : };
      41             : using ChildLoadBalancerCreatorPtr = std::unique_ptr<ChildLoadBalancerCreator>;
      42             : 
      43             : class LegacyChildLoadBalancerCreatorImpl : public Upstream::ChildLoadBalancerCreator {
      44             : public:
      45             :   LegacyChildLoadBalancerCreatorImpl(
      46             :       LoadBalancerType lb_type,
      47             :       OptRef<const envoy::config::cluster::v3::Cluster::RingHashLbConfig> lb_ring_hash_config,
      48             :       OptRef<const envoy::config::cluster::v3::Cluster::MaglevLbConfig> lb_maglev_config,
      49             :       OptRef<const envoy::config::cluster::v3::Cluster::RoundRobinLbConfig> round_robin_config,
      50             :       OptRef<const envoy::config::cluster::v3::Cluster::LeastRequestLbConfig> least_request_config,
      51             :       const envoy::config::cluster::v3::Cluster::CommonLbConfig& common_config);
      52             : 
      53             :   std::pair<Upstream::ThreadAwareLoadBalancerPtr, Upstream::LoadBalancerPtr>
      54             :   createLoadBalancer(const Upstream::PrioritySet& child_priority_set,
      55             :                      const Upstream::PrioritySet* local_priority_set, ClusterLbStats& stats,
      56             :                      Stats::Scope& scope, Runtime::Loader& runtime, Random::RandomGenerator& random,
      57             :                      TimeSource& time_source) override;
      58             : 
      59           0 :   OptRef<const envoy::config::cluster::v3::Cluster::RoundRobinLbConfig> lbRoundRobinConfig() const {
      60           0 :     if (round_robin_config_ != nullptr) {
      61           0 :       return *round_robin_config_;
      62           0 :     }
      63           0 :     return absl::nullopt;
      64           0 :   }
      65             : 
      66           0 :   LoadBalancerType lbType() const { return lb_type_; }
      67             : 
      68             :   OptRef<const envoy::config::cluster::v3::Cluster::LeastRequestLbConfig>
      69           0 :   lbLeastRequestConfig() const {
      70           0 :     if (least_request_config_ != nullptr) {
      71           0 :       return *least_request_config_;
      72           0 :     }
      73           0 :     return absl::nullopt;
      74           0 :   }
      75             : 
      76           0 :   OptRef<const envoy::config::cluster::v3::Cluster::MaglevLbConfig> lbMaglevConfig() const {
      77           0 :     if (lb_maglev_config_ != nullptr) {
      78           0 :       return *lb_maglev_config_;
      79           0 :     }
      80           0 :     return absl::nullopt;
      81           0 :   }
      82             : 
      83           0 :   OptRef<const envoy::config::cluster::v3::Cluster::RingHashLbConfig> lbRingHashConfig() const {
      84           0 :     if (lb_ring_hash_config_ != nullptr) {
      85           0 :       return *lb_ring_hash_config_;
      86           0 :     }
      87           0 :     return absl::nullopt;
      88           0 :   }
      89             : 
      90             : private:
      91             :   const LoadBalancerType lb_type_;
      92             :   const std::unique_ptr<const envoy::config::cluster::v3::Cluster::RingHashLbConfig>
      93             :       lb_ring_hash_config_;
      94             :   const std::unique_ptr<const envoy::config::cluster::v3::Cluster::MaglevLbConfig>
      95             :       lb_maglev_config_;
      96             :   const std::unique_ptr<const envoy::config::cluster::v3::Cluster::RoundRobinLbConfig>
      97             :       round_robin_config_;
      98             :   const std::unique_ptr<const envoy::config::cluster::v3::Cluster::LeastRequestLbConfig>
      99             :       least_request_config_;
     100             :   const envoy::config::cluster::v3::Cluster::CommonLbConfig common_config_;
     101             : };
     102             : 
     103             : using HostHashSet = absl::flat_hash_set<HostSharedPtr>;
     104             : 
     105             : class SubsetLoadBalancerConfig : public Upstream::LoadBalancerConfig {
     106             : public:
     107             :   SubsetLoadBalancerConfig(const SubsetLoadbalancingPolicyProto& subset_config,
     108             :                            ProtobufMessage::ValidationVisitor& visitor);
     109             : 
     110             :   SubsetLoadBalancerConfig(const LegacySubsetLoadbalancingPolicyProto& subset_config,
     111             :                            Upstream::LoadBalancerConfigPtr sub_load_balancer_config,
     112             :                            Upstream::TypedLoadBalancerFactory* sub_load_balancer_factory)
     113             :       : subset_info_(subset_config), sub_load_balancer_config_(std::move(sub_load_balancer_config)),
     114           0 :         sub_load_balancer_factory_(sub_load_balancer_factory) {
     115           0 :     ASSERT(sub_load_balancer_factory_ != nullptr, "sub_load_balancer_factory_ must not be nullptr");
     116           0 :   }
     117             : 
     118             :   Upstream::ThreadAwareLoadBalancerPtr
     119             :   createLoadBalancer(const Upstream::ClusterInfo& cluster_info,
     120             :                      const Upstream::PrioritySet& child_priority_set, Runtime::Loader& runtime,
     121           0 :                      Random::RandomGenerator& random, TimeSource& time_source) const {
     122           0 :     return sub_load_balancer_factory_->create(*sub_load_balancer_config_, cluster_info,
     123           0 :                                               child_priority_set, runtime, random, time_source);
     124           0 :   }
     125             : 
     126           0 :   const Upstream::LoadBalancerSubsetInfo& subsetInfo() const { return subset_info_; }
     127             : 
     128             : private:
     129             :   LoadBalancerSubsetInfoImpl subset_info_;
     130             : 
     131             :   Upstream::LoadBalancerConfigPtr sub_load_balancer_config_;
     132             :   Upstream::TypedLoadBalancerFactory* sub_load_balancer_factory_{};
     133             : };
     134             : 
     135             : class SubsetLoadBalancer : public LoadBalancer, Logger::Loggable<Logger::Id::upstream> {
     136             : public:
     137             :   SubsetLoadBalancer(const LoadBalancerSubsetInfo& subsets, ChildLoadBalancerCreatorPtr child_lb,
     138             :                      const PrioritySet& priority_set, const PrioritySet* local_priority_set,
     139             :                      ClusterLbStats& stats, Stats::Scope& scope, Runtime::Loader& runtime,
     140             :                      Random::RandomGenerator& random, TimeSource& time_source);
     141             :   ~SubsetLoadBalancer() override;
     142             : 
     143             :   // Upstream::LoadBalancer
     144             :   HostConstSharedPtr chooseHost(LoadBalancerContext* context) override;
     145             :   // TODO(alyssawilk) implement for non-metadata match.
     146           0 :   HostConstSharedPtr peekAnotherHost(LoadBalancerContext*) override { return nullptr; }
     147             :   // Pool selection not implemented.
     148             :   absl::optional<Upstream::SelectedPoolAndConnection>
     149             :   selectExistingConnection(Upstream::LoadBalancerContext* /*context*/,
     150             :                            const Upstream::Host& /*host*/,
     151           0 :                            std::vector<uint8_t>& /*hash_key*/) override {
     152           0 :     return absl::nullopt;
     153           0 :   }
     154             :   // Lifetime tracking not implemented.
     155           0 :   OptRef<Envoy::Http::ConnectionPool::ConnectionLifetimeCallbacks> lifetimeCallbacks() override {
     156           0 :     return {};
     157           0 :   }
     158             : 
     159             : private:
     160             :   struct SubsetSelectorFallbackParams;
     161             : 
     162             :   void initSubsetAnyOnce();
     163             :   void initSubsetDefaultOnce();
     164             :   void initSubsetSelectorMap();
     165             :   void initSelectorFallbackSubset(const envoy::config::cluster::v3::Cluster::LbSubsetConfig::
     166             :                                       LbSubsetSelector::LbSubsetSelectorFallbackPolicy&);
     167             :   HostConstSharedPtr
     168             :   chooseHostForSelectorFallbackPolicy(const SubsetSelectorFallbackParams& fallback_params,
     169             :                                       LoadBalancerContext* context);
     170             : 
     171             :   HostConstSharedPtr chooseHostIteration(LoadBalancerContext* context);
     172             : 
     173             :   // Represents a subset of an original HostSet.
     174             :   class HostSubsetImpl : public HostSetImpl {
     175             :   public:
     176             :     HostSubsetImpl(const HostSet& original_host_set, bool locality_weight_aware,
     177             :                    bool scale_locality_weight)
     178             :         : HostSetImpl(original_host_set.priority(), original_host_set.weightedPriorityHealth(),
     179             :                       original_host_set.overprovisioningFactor()),
     180             :           original_host_set_(original_host_set), locality_weight_aware_(locality_weight_aware),
     181           0 :           scale_locality_weight_(scale_locality_weight) {}
     182             : 
     183             :     void update(const HostHashSet& matching_hosts, const HostVector& hosts_added,
     184             :                 const HostVector& hosts_removed);
     185             :     LocalityWeightsConstSharedPtr
     186             :     determineLocalityWeights(const HostsPerLocality& hosts_per_locality) const;
     187             : 
     188             :   private:
     189             :     const HostSet& original_host_set_;
     190             :     const bool locality_weight_aware_;
     191             :     const bool scale_locality_weight_;
     192             :   };
     193             : 
     194             :   // Represents a subset of an original PrioritySet.
     195             :   class PrioritySubsetImpl : public PrioritySetImpl {
     196             :   public:
     197             :     PrioritySubsetImpl(const SubsetLoadBalancer& subset_lb, bool locality_weight_aware,
     198             :                        bool scale_locality_weight);
     199             : 
     200             :     void update(uint32_t priority, const HostHashSet& matching_hosts, const HostVector& hosts_added,
     201             :                 const HostVector& hosts_removed);
     202             : 
     203           0 :     bool empty() const { return empty_; }
     204             : 
     205           0 :     void triggerCallbacks() {
     206           0 :       for (size_t i = 0; i < hostSetsPerPriority().size(); ++i) {
     207           0 :         runReferenceUpdateCallbacks(i, {}, {});
     208           0 :       }
     209           0 :     }
     210             : 
     211             :     void updateSubset(uint32_t priority, const HostHashSet& matching_hosts,
     212           0 :                       const HostVector& hosts_added, const HostVector& hosts_removed) {
     213           0 :       reinterpret_cast<HostSubsetImpl*>(host_sets_[priority].get())
     214           0 :           ->update(matching_hosts, hosts_added, hosts_removed);
     215           0 :       runUpdateCallbacks(hosts_added, hosts_removed);
     216           0 :     }
     217             : 
     218             :     // Thread aware LB if applicable.
     219             :     ThreadAwareLoadBalancerPtr thread_aware_lb_;
     220             :     // Current active LB.
     221             :     LoadBalancerPtr lb_;
     222             : 
     223             :   protected:
     224             :     HostSetImplPtr createHostSet(uint32_t priority, absl::optional<bool> weighted_priority_health,
     225             :                                  absl::optional<uint32_t> overprovisioning_factor) override;
     226             : 
     227             :   private:
     228             :     const PrioritySet& original_priority_set_;
     229             :     const PrioritySet* original_local_priority_set_{};
     230             :     const bool locality_weight_aware_;
     231             :     const bool scale_locality_weight_;
     232             :     bool empty_ = true;
     233             :   };
     234             : 
     235             :   using HostSubsetImplPtr = std::unique_ptr<HostSubsetImpl>;
     236             :   using PrioritySubsetImplPtr = std::unique_ptr<PrioritySubsetImpl>;
     237             : 
     238             :   using SubsetMetadata = std::vector<std::pair<std::string, ProtobufWkt::Value>>;
     239             : 
     240             :   class LbSubsetEntry;
     241             :   struct SubsetSelectorMap;
     242             : 
     243             :   using LbSubsetEntryPtr = std::shared_ptr<LbSubsetEntry>;
     244             :   using SubsetSelectorMapPtr = std::shared_ptr<SubsetSelectorMap>;
     245             :   using ValueSubsetMap = absl::node_hash_map<HashedValue, LbSubsetEntryPtr>;
     246             :   using LbSubsetMap = absl::node_hash_map<std::string, ValueSubsetMap>;
     247             :   using SubsetSelectorFallbackParamsRef = std::reference_wrapper<SubsetSelectorFallbackParams>;
     248             :   using MetadataFallbacks = ProtobufWkt::RepeatedPtrField<ProtobufWkt::Value>;
     249             : 
     250             : public:
     251             :   class LoadBalancerContextWrapper : public LoadBalancerContext {
     252             :   public:
     253             :     LoadBalancerContextWrapper(LoadBalancerContext* wrapped,
     254             :                                const std::set<std::string>& filtered_metadata_match_criteria_names);
     255             : 
     256             :     LoadBalancerContextWrapper(LoadBalancerContext* wrapped,
     257             :                                Router::MetadataMatchCriteriaConstPtr metadata_match_criteria)
     258           0 :         : wrapped_(wrapped), metadata_match_(std::move(metadata_match_criteria)) {}
     259             : 
     260             :     LoadBalancerContextWrapper(LoadBalancerContext* wrapped,
     261             :                                const ProtobufWkt::Struct& metadata_match_criteria_override);
     262             :     // LoadBalancerContext
     263           0 :     absl::optional<uint64_t> computeHashKey() override { return wrapped_->computeHashKey(); }
     264           0 :     const Router::MetadataMatchCriteria* metadataMatchCriteria() override {
     265           0 :       return metadata_match_.get();
     266           0 :     }
     267           0 :     const Network::Connection* downstreamConnection() const override {
     268           0 :       return wrapped_->downstreamConnection();
     269           0 :     }
     270           0 :     const StreamInfo::StreamInfo* requestStreamInfo() const override {
     271           0 :       return wrapped_->requestStreamInfo();
     272           0 :     }
     273           0 :     const Http::RequestHeaderMap* downstreamHeaders() const override {
     274           0 :       return wrapped_->downstreamHeaders();
     275           0 :     }
     276             :     const HealthyAndDegradedLoad& determinePriorityLoad(
     277             :         const PrioritySet& priority_set, const HealthyAndDegradedLoad& original_priority_load,
     278           0 :         const Upstream::RetryPriority::PriorityMappingFunc& priority_mapping_func) override {
     279           0 :       return wrapped_->determinePriorityLoad(priority_set, original_priority_load,
     280           0 :                                              priority_mapping_func);
     281           0 :     }
     282           0 :     bool shouldSelectAnotherHost(const Host& host) override {
     283           0 :       return wrapped_->shouldSelectAnotherHost(host);
     284           0 :     }
     285           0 :     uint32_t hostSelectionRetryCount() const override {
     286           0 :       return wrapped_->hostSelectionRetryCount();
     287           0 :     }
     288           0 :     Network::Socket::OptionsSharedPtr upstreamSocketOptions() const override {
     289           0 :       return wrapped_->upstreamSocketOptions();
     290           0 :     }
     291           0 :     Network::TransportSocketOptionsConstSharedPtr upstreamTransportSocketOptions() const override {
     292           0 :       return wrapped_->upstreamTransportSocketOptions();
     293           0 :     }
     294             : 
     295           0 :     absl::optional<OverrideHost> overrideHostToSelect() const override {
     296           0 :       return wrapped_->overrideHostToSelect();
     297           0 :     }
     298             : 
     299             :   private:
     300             :     LoadBalancerContext* wrapped_;
     301             :     Router::MetadataMatchCriteriaConstPtr metadata_match_;
     302             :   };
     303             : 
     304             : private:
     305             :   struct SubsetSelectorFallbackParams {
     306             :     envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetSelector::
     307             :         LbSubsetSelectorFallbackPolicy fallback_policy_;
     308             :     const std::set<std::string>* fallback_keys_subset_ = nullptr;
     309             :   };
     310             : 
     311             :   struct SubsetSelectorMap {
     312             :     absl::node_hash_map<std::string, SubsetSelectorMapPtr> subset_keys_;
     313             :     SubsetSelectorFallbackParams fallback_params_;
     314             :   };
     315             : 
     316             :   class LbSubset {
     317             :   public:
     318           0 :     virtual ~LbSubset() = default;
     319             :     virtual HostConstSharedPtr chooseHost(LoadBalancerContext* context) const PURE;
     320             :     virtual void pushHost(uint32_t priority, HostSharedPtr host) PURE;
     321             :     virtual void finalize(uint32_t priority) PURE;
     322             :     virtual bool active() const PURE;
     323             :   };
     324             :   using LbSubsetPtr = std::unique_ptr<LbSubset>;
     325             : 
     326             :   class PriorityLbSubset : public LbSubset {
     327             :   public:
     328             :     PriorityLbSubset(const SubsetLoadBalancer& subset_lb, bool locality_weight_aware,
     329             :                      bool scale_locality_weight)
     330           0 :         : subset_(subset_lb, locality_weight_aware, scale_locality_weight) {}
     331             : 
     332             :     // Subset
     333           0 :     HostConstSharedPtr chooseHost(LoadBalancerContext* context) const override {
     334           0 :       return subset_.lb_->chooseHost(context);
     335           0 :     }
     336           0 :     void pushHost(uint32_t priority, HostSharedPtr host) override {
     337           0 :       while (host_sets_.size() <= priority) {
     338           0 :         host_sets_.push_back({HostHashSet(), HostHashSet()});
     339           0 :       }
     340           0 :       host_sets_[priority].second.emplace(std::move(host));
     341           0 :     }
     342             :     // Called after pushHost. Update subset by the hosts that pushed in the pushHost. If no any host
     343             :     // is pushed then subset_ will be set to empty.
     344           0 :     void finalize(uint32_t priority) override {
     345           0 :       while (host_sets_.size() <= priority) {
     346           0 :         host_sets_.push_back({HostHashSet(), HostHashSet()});
     347           0 :       }
     348           0 :       auto& [old_hosts, new_hosts] = host_sets_[priority];
     349             : 
     350           0 :       HostVector added;
     351           0 :       HostVector removed;
     352             : 
     353           0 :       for (const auto& host : old_hosts) {
     354           0 :         if (new_hosts.count(host) == 0) {
     355           0 :           removed.emplace_back(host);
     356           0 :         }
     357           0 :       }
     358             : 
     359           0 :       for (const auto& host : new_hosts) {
     360           0 :         if (old_hosts.count(host) == 0) {
     361           0 :           added.emplace_back(host);
     362           0 :         }
     363           0 :       }
     364             : 
     365           0 :       subset_.update(priority, new_hosts, added, removed);
     366             : 
     367           0 :       old_hosts.swap(new_hosts);
     368           0 :       new_hosts.clear();
     369           0 :     }
     370             : 
     371           0 :     bool active() const override { return !subset_.empty(); }
     372             : 
     373             :     std::vector<std::pair<HostHashSet, HostHashSet>> host_sets_;
     374             :     PrioritySubsetImpl subset_;
     375             :   };
     376             : 
     377             :   class SingleHostLbSubset : public LbSubset {
     378             :     // Subset
     379           0 :     HostConstSharedPtr chooseHost(LoadBalancerContext*) const override { return subset_; }
     380             :     // This is called at most once for every update for single host subset.
     381           0 :     void pushHost(uint32_t priority, HostSharedPtr host) override {
     382           0 :       new_hosts_[priority] = std::move(host);
     383           0 :     }
     384             :     // Called after pushHost. Update subset by the host that pushed in the pushHost. If no any host
     385             :     // is pushed then subset_ will be set to nullptr.
     386           0 :     void finalize(uint32_t priority) override {
     387           0 :       if (auto iter = new_hosts_.find(priority); iter == new_hosts_.end()) {
     388             :         // No any host for current subset and priority. Try remove record in the hosts_.
     389           0 :         hosts_.erase(priority);
     390           0 :       } else {
     391             :         // Single host is set for current subset and priority.
     392           0 :         hosts_[priority] = std::move(iter->second);
     393           0 :         new_hosts_.erase(priority);
     394           0 :       }
     395             : 
     396           0 :       if (hosts_.empty()) {
     397           0 :         subset_ = nullptr;
     398           0 :         return;
     399           0 :       }
     400             : 
     401           0 :       subset_ = hosts_.begin()->second;
     402           0 :     }
     403           0 :     bool active() const override { return subset_ != nullptr; }
     404             : 
     405             :     // We will update subsets for every priority separately and these simple map can help us
     406             :     // to ensure which priority has valid host quickly.
     407             :     std::map<uint32_t, HostSharedPtr> hosts_;
     408             :     std::map<uint32_t, HostSharedPtr> new_hosts_;
     409             :     HostConstSharedPtr subset_;
     410             :   };
     411             : 
     412             :   // Entry in the subset hierarchy.
     413             :   class LbSubsetEntry {
     414             :   public:
     415           0 :     LbSubsetEntry() = default;
     416             : 
     417           0 :     bool initialized() const { return lb_subset_ != nullptr; }
     418           0 :     bool active() const { return initialized() && lb_subset_->active(); }
     419           0 :     bool hasChildren() const { return !children_.empty(); }
     420             : 
     421             :     LbSubsetMap children_;
     422             : 
     423             :     // Only initialized if a match exists at this level.
     424             :     LbSubsetPtr lb_subset_;
     425             : 
     426             :     // Used to quick check if entry is single host subset entry or not.
     427             :     bool single_host_subset_{};
     428             :   };
     429             : 
     430             :   void initLbSubsetEntryOnce(LbSubsetEntryPtr& entry, bool single_host_subset);
     431             : 
     432             :   // Create filtered default subset (if necessary) and other subsets based on current hosts.
     433             :   void refreshSubsets();
     434             :   void refreshSubsets(uint32_t priority);
     435             : 
     436             :   // Called by HostSet::MemberUpdateCb
     437             :   void update(uint32_t priority, const HostVector& all_hosts);
     438             : 
     439             :   void updateFallbackSubset(uint32_t priority, const HostVector& all_hosts);
     440             :   void processSubsets(uint32_t priority, const HostVector& all_hosts);
     441             : 
     442             :   HostConstSharedPtr tryChooseHostFromContext(LoadBalancerContext* context, bool& host_chosen);
     443             : 
     444             :   absl::optional<SubsetSelectorFallbackParamsRef>
     445             :   tryFindSelectorFallbackParams(LoadBalancerContext* context);
     446             : 
     447             :   bool hostMatches(const SubsetMetadata& kvs, const Host& host);
     448             : 
     449             :   LbSubsetEntryPtr
     450             :   findSubset(const std::vector<Router::MetadataMatchCriterionConstSharedPtr>& matches);
     451             : 
     452             :   LbSubsetEntryPtr findOrCreateLbSubsetEntry(LbSubsetMap& subsets, const SubsetMetadata& kvs,
     453             :                                              uint32_t idx);
     454             :   void forEachSubset(LbSubsetMap& subsets, std::function<void(LbSubsetEntryPtr&)> cb);
     455             :   void purgeEmptySubsets(LbSubsetMap& subsets);
     456             : 
     457             :   std::vector<SubsetMetadata> extractSubsetMetadata(const std::set<std::string>& subset_keys,
     458             :                                                     const Host& host);
     459             :   std::string describeMetadata(const SubsetMetadata& kvs);
     460             :   HostConstSharedPtr chooseHostWithMetadataFallbacks(LoadBalancerContext* context,
     461             :                                                      const MetadataFallbacks& metadata_fallbacks);
     462             :   const ProtobufWkt::Value* getMetadataFallbackList(LoadBalancerContext* context) const;
     463             :   LoadBalancerContextWrapper removeMetadataFallbackList(LoadBalancerContext* context);
     464             : 
     465             :   ClusterLbStats& stats_;
     466             :   Stats::Scope& scope_;
     467             :   Runtime::Loader& runtime_;
     468             :   Random::RandomGenerator& random_;
     469             :   TimeSource& time_source_;
     470             : 
     471             :   const envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetFallbackPolicy
     472             :       fallback_policy_;
     473             :   const envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetMetadataFallbackPolicy
     474             :       metadata_fallback_policy_;
     475             :   const SubsetMetadata default_subset_metadata_;
     476             :   std::vector<SubsetSelectorPtr> subset_selectors_;
     477             : 
     478             :   const PrioritySet& original_priority_set_;
     479             :   const PrioritySet* original_local_priority_set_;
     480             :   Common::CallbackHandlePtr original_priority_set_callback_handle_;
     481             : 
     482             :   ChildLoadBalancerCreatorPtr child_lb_creator_;
     483             : 
     484             :   LbSubsetEntryPtr subset_any_;
     485             :   LbSubsetEntryPtr subset_default_;
     486             : 
     487             :   // Reference to sub_set_any_ or subset_default_.
     488             :   LbSubsetEntryPtr fallback_subset_;
     489             :   LbSubsetEntryPtr panic_mode_subset_;
     490             : 
     491             :   // Forms a trie-like structure. Requires lexically sorted Host and Route metadata.
     492             :   LbSubsetMap subsets_;
     493             :   // Forms a trie-like structure of lexically sorted keys+fallback policy from subset
     494             :   // selectors configuration
     495             :   SubsetSelectorMapPtr selectors_;
     496             : 
     497             :   Stats::Gauge* single_duplicate_stat_{};
     498             : 
     499             :   // Keep small members (bools and enums) at the end of class, to reduce alignment overhead.
     500             :   const bool locality_weight_aware_ : 1;
     501             :   const bool scale_locality_weight_ : 1;
     502             :   const bool list_as_any_ : 1;
     503             :   const bool allow_redundant_keys_{};
     504             : 
     505             :   friend class SubsetLoadBalancerInternalStateTester;
     506             : };
     507             : 
     508             : } // namespace Upstream
     509             : } // namespace Envoy

Generated by: LCOV version 1.15