1
#pragma once
2

            
3
#include "envoy/common/pure.h"
4
#include "envoy/http/async_client.h"
5
#include "envoy/tcp/async_tcp_client.h"
6
#include "envoy/upstream/load_balancer.h"
7
#include "envoy/upstream/upstream.h"
8

            
9
namespace Envoy {
10
namespace Upstream {
11

            
12
// HttpPoolData returns information about a given pool as well as a function
13
// to create streams on that pool.
14
class HttpPoolData {
15
public:
16
  using OnNewStreamFn = std::function<void()>;
17

            
18
  HttpPoolData(OnNewStreamFn on_new_stream, Http::ConnectionPool::Instance* pool)
19
90345
      : on_new_stream_(on_new_stream), pool_(pool) {}
20

            
21
  /**
22
   * See documentation of Http::ConnectionPool::Instance.
23
   */
24
  Envoy::Http::ConnectionPool::Cancellable*
25
  newStream(Http::ResponseDecoder& response_decoder,
26
            Envoy::Http::ConnectionPool::Callbacks& callbacks,
27
47527
            const Http::ConnectionPool::Instance::StreamOptions& stream_options) {
28
47527
    on_new_stream_();
29
47527
    return pool_->newStream(response_decoder, callbacks, stream_options);
30
47527
  }
31
1
  bool hasActiveConnections() const { return pool_->hasActiveConnections(); };
32

            
33
  /**
34
   * See documentation of Envoy::ConnectionPool::Instance.
35
   */
36
1
  void addIdleCallback(ConnectionPool::Instance::IdleCb cb) { pool_->addIdleCallback(cb); };
37
1
  void drainConnections(ConnectionPool::DrainBehavior drain_behavior) {
38
1
    pool_->drainConnections(drain_behavior);
39
1
  };
40

            
41
93462
  Upstream::HostDescriptionConstSharedPtr host() const { return pool_->host(); }
42

            
43
private:
44
  friend class HttpPoolDataPeer;
45

            
46
  OnNewStreamFn on_new_stream_;
47
  Http::ConnectionPool::Instance* pool_;
48
};
49

            
50
// Tcp pool returns information about a given pool, as well as a function to
51
// create connections on that pool.
52
class TcpPoolData {
53
public:
54
  using OnNewConnectionFn = std::function<void()>;
55

            
56
  TcpPoolData(OnNewConnectionFn on_new_connection, Tcp::ConnectionPool::Instance* pool)
57
88640
      : on_new_connection_(on_new_connection), pool_(pool) {}
58

            
59
  Envoy::Tcp::ConnectionPool::Cancellable*
60
2586
  newConnection(Envoy::Tcp::ConnectionPool::Callbacks& callbacks) {
61
2586
    on_new_connection_();
62
2586
    return pool_->newConnection(callbacks);
63
2586
  }
64

            
65
773
  Upstream::HostDescriptionConstSharedPtr host() const { return pool_->host(); }
66

            
67
private:
68
  friend class TcpPoolDataPeer;
69
  OnNewConnectionFn on_new_connection_;
70
  Tcp::ConnectionPool::Instance* pool_;
71
};
72

            
73
/**
74
 * A thread local cluster instance that can be used for direct load balancing and host set
75
 * interactions. In general, an instance of ThreadLocalCluster can only be safely used in the
76
 * direct call context after it is retrieved from the cluster manager. See ClusterManager::get()
77
 * for more information.
78
 */
79
class ThreadLocalCluster {
80
public:
81
76956
  virtual ~ThreadLocalCluster() = default;
82

            
83
  /**
84
   * @return const PrioritySet& the backing priority set.
85
   */
86
  virtual const PrioritySet& prioritySet() PURE;
87

            
88
  /**
89
   * @return ClusterInfoConstSharedPtr the info for this cluster. The info is safe to store beyond
90
   * the lifetime of the ThreadLocalCluster instance itself.
91
   */
92
  virtual ClusterInfoConstSharedPtr info() PURE;
93

            
94
  /**
95
   * @return LoadBalancer& the backing load balancer.
96
   */
97
  virtual LoadBalancer& loadBalancer() PURE;
98

            
99
  /* Choose a host for the next request. If this returns a host, this should immediately be
100
   * followed by a call to httpConnPool or tcpConnPool or load balancing may not work as
101
   * expected.
102
   *
103
   * @param context the optional load balancer context.
104
   * @return host the next host selected by the load balancer or null if no host
105
   * is available.
106
   */
107
  virtual HostSelectionResponse chooseHost(LoadBalancerContext* context) PURE;
108

            
109
  /**
110
   * Allocate a load balanced HTTP connection pool for a cluster. This is *per-thread* so that
111
   * callers do not need to worry about per thread synchronization. The load balancing policy that
112
   * is used is the one defined on the cluster when it was created.
113
   *
114
   * @param priority the connection pool priority.
115
   * @param downstream_protocol the downstream protocol (if one exists) to use in protocol
116
   *        selection.
117
   * @param context the optional load balancer context. Must continue to be
118
   *        valid until newConnection is called on the pool (if it is to be called).
119
   * @return the connection pool data or nullopt if there is no host available in the cluster.
120
   */
121
  virtual absl::optional<HttpPoolData>
122
  httpConnPool(HostConstSharedPtr host, ResourcePriority priority,
123
               absl::optional<Http::Protocol> downstream_protocol,
124
               LoadBalancerContext* context) PURE;
125

            
126
  /**
127
   * Allocate a load balanced TCP connection pool for a cluster. This is *per-thread* so that
128
   * callers do not need to worry about per thread synchronization. The load balancing policy that
129
   * is used is the one defined on the cluster when it was created.
130
   *
131
   * @param priority the connection pool priority.
132
   * @param context the optional load balancer context. Must continue to be
133
   *        valid until newConnection is called on the pool (if it is to be called).
134
   * @return the connection pool data or nullopt if there is no host available in the cluster.
135
   */
136
  virtual absl::optional<TcpPoolData> tcpConnPool(HostConstSharedPtr host,
137
                                                  ResourcePriority priority,
138
                                                  LoadBalancerContext* context) PURE;
139

            
140
  /* a legacy API which synchronously chooses a host and creates a conn pool*/
141
  virtual absl::optional<TcpPoolData> tcpConnPool(ResourcePriority priority,
142
                                                  LoadBalancerContext* context) PURE;
143

            
144
  /**
145
   * Allocate a load balanced TCP connection for a cluster. The created connection is already
146
   * bound to the correct *per-thread* dispatcher, so no further synchronization is needed. The
147
   * load balancing policy that is used is the one defined on the cluster when it was created.
148
   *
149
   * @param context the optional load balancer context.
150
   * @return both a connection and the host that backs the connection. Both can be nullptr if there
151
   *         is no host available in the cluster.
152
   */
153
  virtual Host::CreateConnectionData tcpConn(LoadBalancerContext* context) PURE;
154

            
155
  /**
156
   * @return a client that can be used to make async HTTP calls against the given cluster. The
157
   * client may be backed by a connection pool or by a multiplexed connection. The cluster manager
158
   * owns the client.
159
   */
160
  virtual Http::AsyncClient& httpAsyncClient() PURE;
161

            
162
  /**
163
   * @param context the optional load balancer context.
164
   * @param options the tcp client creation config options.
165
   * @return a client that can be used to make async Tcp calls against the given cluster.
166
   */
167
  virtual Tcp::AsyncTcpClientPtr
168
  tcpAsyncClient(LoadBalancerContext* context,
169
                 Tcp::AsyncTcpClientOptionsConstSharedPtr options) PURE;
170

            
171
  /**
172
   * @return the thread local cluster drop_overload configuration.
173
   */
174
  virtual UnitFloat dropOverload() const PURE;
175

            
176
  /**
177
   * @return the thread local cluster drop_category configuration.
178
   */
179
  virtual const std::string& dropCategory() const PURE;
180

            
181
  /**
182
   * Set up the drop_overload value for the thread local cluster.
183
   */
184
  virtual void setDropOverload(UnitFloat drop_overload) PURE;
185

            
186
  /**
187
   * Set up the drop_category value for the thread local cluster.
188
   */
189
  virtual void setDropCategory(absl::string_view drop_category) PURE;
190
};
191

            
192
using ThreadLocalClusterOptRef = absl::optional<std::reference_wrapper<ThreadLocalCluster>>;
193

            
194
} // namespace Upstream
195
} // namespace Envoy