1
#pragma once
2

            
3
#include "envoy/api/api.h"
4
#include "envoy/config/bootstrap/v3/bootstrap.pb.h"
5
#include "envoy/config/core/v3/grpc_service.pb.h"
6
#include "envoy/grpc/async_client_manager.h"
7
#include "envoy/singleton/manager.h"
8
#include "envoy/stats/scope.h"
9
#include "envoy/thread_local/thread_local.h"
10
#include "envoy/upstream/cluster_manager.h"
11

            
12
#include "source/common/grpc/stat_names.h"
13
#include "source/common/protobuf/utility.h"
14

            
15
namespace Envoy {
16
namespace Grpc {
17

            
18
class AsyncClientFactoryImpl : public AsyncClientFactory {
19
public:
20
  AsyncClientFactoryImpl(const envoy::config::core::v3::GrpcService& config,
21
                         bool skip_cluster_check,
22
                         Server::Configuration::CommonFactoryContext& context,
23
                         absl::Status& creation_status);
24
  absl::StatusOr<RawAsyncClientPtr> createUncachedRawAsyncClient() override;
25

            
26
private:
27
  const envoy::config::core::v3::GrpcService config_;
28
  Server::Configuration::CommonFactoryContext& context_;
29
};
30

            
31
class GoogleAsyncClientFactoryImpl : public AsyncClientFactory {
32
public:
33
  GoogleAsyncClientFactoryImpl(const envoy::config::core::v3::GrpcService& config,
34
                               ThreadLocal::Slot* google_tls_slot, Stats::Scope& scope,
35
                               Server::Configuration::CommonFactoryContext& context,
36
                               const StatNames& stat_names, absl::Status& creation_status);
37
  absl::StatusOr<RawAsyncClientPtr> createUncachedRawAsyncClient() override;
38

            
39
private:
40
  ThreadLocal::Slot* google_tls_slot_;
41
  Stats::ScopeSharedPtr scope_;
42
  const envoy::config::core::v3::GrpcService config_;
43
  Server::Configuration::CommonFactoryContext& factory_context_;
44
  const StatNames& stat_names_;
45
};
46

            
47
class AsyncClientManagerImpl : public AsyncClientManager {
48
public:
49
  AsyncClientManagerImpl(
50
      const envoy::config::bootstrap::v3::Bootstrap::GrpcAsyncClientManagerConfig& config,
51
      Server::Configuration::CommonFactoryContext& context, const StatNames& stat_names);
52
  absl::StatusOr<RawAsyncClientSharedPtr>
53
  getOrCreateRawAsyncClient(const envoy::config::core::v3::GrpcService& config, Stats::Scope& scope,
54
                            bool skip_cluster_check) override;
55

            
56
  absl::StatusOr<RawAsyncClientSharedPtr>
57
  getOrCreateRawAsyncClientWithHashKey(const GrpcServiceConfigWithHashKey& config_with_hash_key,
58
                                       Stats::Scope& scope, bool skip_cluster_check) override;
59

            
60
  absl::StatusOr<AsyncClientFactoryPtr>
61
  factoryForGrpcService(const envoy::config::core::v3::GrpcService& config, Stats::Scope& scope,
62
                        bool skip_cluster_check) override;
63
  class RawAsyncClientCache : public ThreadLocal::ThreadLocalObject {
64
  public:
65
    explicit RawAsyncClientCache(Event::Dispatcher& dispatcher,
66
                                 std::chrono::milliseconds max_cached_entry_idle_duration);
67
    void setCache(const GrpcServiceConfigWithHashKey& config_with_hash_key,
68
                  const RawAsyncClientSharedPtr& client);
69

            
70
    RawAsyncClientSharedPtr getCache(const GrpcServiceConfigWithHashKey& config_with_hash_key);
71

            
72
  private:
73
    void evictEntriesAndResetEvictionTimer();
74
    struct CacheEntry {
75
      CacheEntry(const GrpcServiceConfigWithHashKey& config_with_hash_key,
76
                 RawAsyncClientSharedPtr const& client, MonotonicTime create_time)
77
875
          : config_with_hash_key_(config_with_hash_key), client_(client),
78
875
            accessed_time_(create_time) {}
79
      GrpcServiceConfigWithHashKey config_with_hash_key_;
80
      RawAsyncClientSharedPtr client_;
81
      MonotonicTime accessed_time_;
82
    };
83
    using LruList = std::list<CacheEntry>;
84
    LruList lru_list_;
85
    absl::flat_hash_map<GrpcServiceConfigWithHashKey, LruList::iterator> lru_map_;
86
    Event::Dispatcher& dispatcher_;
87
    Envoy::Event::TimerPtr cache_eviction_timer_;
88
    const std::chrono::milliseconds max_cached_entry_idle_duration_;
89
  };
90

            
91
private:
92
  Server::Configuration::CommonFactoryContext& context_;
93
  ThreadLocal::SlotPtr google_tls_slot_;
94
  const StatNames& stat_names_;
95
  ThreadLocal::TypedSlot<RawAsyncClientCache> raw_async_client_cache_;
96
};
97

            
98
} // namespace Grpc
99
} // namespace Envoy