userver: userver/ugrpc/client/impl/channel_cache.hpp Source File
Loading...
Searching...
No Matches
channel_cache.hpp
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <memory>
6#include <string>
7#include <unordered_map>
8
9#include <grpcpp/channel.h>
10#include <grpcpp/security/credentials.h>
11#include <grpcpp/support/channel_arguments.h>
12
13#include <userver/concurrent/variable.hpp>
14#include <userver/utils/fixed_array.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace ugrpc::client::impl {
19
20class ChannelCache final {
21 public:
22 ChannelCache(std::shared_ptr<grpc::ChannelCredentials>&& credentials,
23 const grpc::ChannelArguments& channel_args,
24 std::size_t channel_count);
25
26 ~ChannelCache();
27
28 class Token;
29
30 // The grpc::Channel is kept in cache as long as some Token pointing to it is
31 // alive.
32 Token Get(const std::string& endpoint);
33
34 private:
35 struct CountedChannel final {
36 CountedChannel(const std::string& endpoint,
37 const std::shared_ptr<grpc::ChannelCredentials>& credentials,
38 const grpc::ChannelArguments& channel_args,
39 std::size_t count);
40
41 utils::FixedArray<std::shared_ptr<grpc::Channel>> channels;
42 std::uint64_t counter{0};
43 };
44
45 using Map = std::unordered_map<std::string, CountedChannel>;
46
47 const std::shared_ptr<grpc::ChannelCredentials> credentials_;
48 const grpc::ChannelArguments channel_args_;
49 const std::size_t channel_count_;
50 concurrent::Variable<Map> channels_;
51};
52
53class ChannelCache::Token final {
54 public:
55 Token() noexcept = default;
56
57 // Must be constructed with 'cache.channels_' under lock
58 Token(ChannelCache& cache, const std::string& endpoint,
59 CountedChannel& counted_channel) noexcept;
60
61 Token(Token&&) noexcept;
62 Token& operator=(Token&&) noexcept;
63 ~Token();
64
65 std::size_t GetChannelCount() const noexcept;
66
67 const std::shared_ptr<grpc::Channel>& GetChannel(std::size_t index) const
68 noexcept;
69
70 private:
71 ChannelCache* cache_{nullptr};
72 const std::string* endpoint_{nullptr};
73 CountedChannel* counted_channel_{nullptr};
74};
75
76} // namespace ugrpc::client::impl
77
78USERVER_NAMESPACE_END