1
#pragma once
2

            
3
#include "envoy/common/callback.h"
4
#include "envoy/upstream/load_balancer.h"
5

            
6
#include "source/common/common/logger.h"
7
#include "source/extensions/load_balancing_policies/dynamic_modules/lb_config.h"
8

            
9
namespace Envoy {
10
namespace Extensions {
11
namespace LoadBalancingPolicies {
12
namespace DynamicModules {
13

            
14
/**
15
 * A load balancer implementation that delegates host selection to a dynamic module.
16
 */
17
class DynamicModuleLoadBalancer : public Upstream::LoadBalancer,
18
                                  public Logger::Loggable<Logger::Id::dynamic_modules> {
19
public:
20
  DynamicModuleLoadBalancer(DynamicModuleLbConfigSharedPtr config,
21
                            const Upstream::PrioritySet& priority_set,
22
                            const std::string& cluster_name);
23
  ~DynamicModuleLoadBalancer() override;
24

            
25
  // Upstream::LoadBalancer
26
  Upstream::HostSelectionResponse chooseHost(Upstream::LoadBalancerContext* context) override;
27
  Upstream::HostConstSharedPtr peekAnotherHost(Upstream::LoadBalancerContext* context) override;
28
  OptRef<Envoy::Http::ConnectionPool::ConnectionLifetimeCallbacks> lifetimeCallbacks() override;
29
  absl::optional<Upstream::SelectedPoolAndConnection>
30
  selectExistingConnection(Upstream::LoadBalancerContext* context, const Upstream::Host& host,
31
                           std::vector<uint8_t>& hash_key) override;
32

            
33
  // Accessors for callbacks.
34
4
  const std::string& clusterName() const { return cluster_name_; }
35
167
  const Upstream::PrioritySet& prioritySet() const { return priority_set_; }
36

            
37
  // Per-host custom data storage.
38
  bool setHostData(uint32_t priority, size_t index, uintptr_t data);
39
  bool getHostData(uint32_t priority, size_t index, uintptr_t* data) const;
40

            
41
  // Accessors for hosts added/removed during the on_host_membership_update callback.
42
4
  const Upstream::HostVector* hostsAdded() const { return hosts_added_; }
43
3
  const Upstream::HostVector* hostsRemoved() const { return hosts_removed_; }
44

            
45
private:
46
  DynamicModuleLbConfigSharedPtr config_;
47
  const Upstream::PrioritySet& priority_set_;
48
  std::string cluster_name_;
49
  envoy_dynamic_module_type_lb_module_ptr in_module_lb_;
50

            
51
  // Handle for the member update callback registration. Automatically unregisters on destruction.
52
  Envoy::Common::CallbackHandlePtr member_update_cb_;
53

            
54
  // Temporary pointers to host vectors, valid only during on_host_membership_update callback.
55
  const Upstream::HostVector* hosts_added_{};
56
  const Upstream::HostVector* hosts_removed_{};
57

            
58
  // Per-host data storage keyed by (priority, index). This is per-LB-instance (per-worker).
59
  absl::flat_hash_map<std::pair<uint32_t, size_t>, uintptr_t> per_host_data_;
60
};
61

            
62
} // namespace DynamicModules
63
} // namespace LoadBalancingPolicies
64
} // namespace Extensions
65
} // namespace Envoy