7#include <grpcpp/channel.h> 
    8#include <grpcpp/completion_queue.h> 
   10#include <userver/dynamic_config/source.hpp> 
   11#include <userver/testsuite/grpc_control.hpp> 
   12#include <userver/ugrpc/client/impl/channel_cache.hpp> 
   13#include <userver/ugrpc/client/middlewares/fwd.hpp> 
   14#include <userver/ugrpc/impl/static_metadata.hpp> 
   15#include <userver/ugrpc/impl/statistics.hpp> 
   16#include <userver/utils/fixed_array.hpp> 
   17#include <userver/utils/rand.hpp> 
   19USERVER_NAMESPACE_BEGIN
 
   21namespace ugrpc::
client::impl {
 
   23struct ClientParams 
final {
 
   24  std::string client_name;
 
   26  grpc::CompletionQueue& queue;
 
   27  ugrpc::impl::ServiceStatistics& statistics_storage;
 
   28  impl::ChannelCache::Token channel_token;
 
   29  const dynamic_config::Source config_source;
 
   34class ClientData 
final {
 
   36  template <
typename Service>
 
   37  using Stub = 
typename Service::Stub;
 
   39  ClientData() = 
delete;
 
   41  template <
typename Service>
 
   42  ClientData(ClientParams&& params, ugrpc::impl::StaticServiceMetadata metadata,
 
   43             std::in_place_type_t<Service>)
 
   44      : params_(std::move(params)), metadata_(metadata) {
 
   45    const std::size_t channel_count = GetChannelToken().GetChannelCount();
 
   46    stubs_ = utils::GenerateFixedArray(channel_count, [&](std::size_t index) {
 
   48          Service::NewStub(GetChannelToken().GetChannel(index)).release(),
 
   49          &StubDeleter<Service>);
 
   53  ClientData(ClientData&&) 
noexcept = 
default;
 
   54  ClientData& operator=(ClientData&&) = 
delete;
 
   56  ClientData(
const ClientData&) = 
delete;
 
   57  ClientData& operator=(
const ClientData&) = 
delete;
 
   59  template <
typename Service>
 
   60  Stub<Service>& NextStub() 
const {
 
   61    return *
static_cast<Stub<Service>*>(
 
   62        stubs_[utils::RandRange(stubs_.size())].get());
 
   65  grpc::CompletionQueue& GetQueue() 
const { 
return params_.queue; }
 
   67  dynamic_config::Snapshot GetConfigSnapshot() 
const {
 
   68    return params_.config_source.GetSnapshot();
 
   71  ugrpc::impl::MethodStatistics& GetStatistics(std::size_t method_id) 
const {
 
   72    return params_.statistics_storage.GetMethodStatistics(method_id);
 
   75  ChannelCache::Token& GetChannelToken() { 
return params_.channel_token; }
 
   77  std::string_view GetClientName() 
const { 
return params_.client_name; }
 
   79  const Middlewares& GetMiddlewares() 
const { 
return params_.mws; }
 
   81  const ugrpc::impl::StaticServiceMetadata& GetMetadata() 
const {
 
   86    return params_.testsuite_grpc;
 
   90  using StubDeleterType = 
void (*)(
void*);
 
   91  using StubPtr = std::unique_ptr<
void, StubDeleterType>;
 
   93  template <
typename Service>
 
   94  static void StubDeleter(
void* ptr) 
noexcept {
 
   95    delete static_cast<Stub<Service>*>(ptr);
 
   99  ugrpc::impl::StaticServiceMetadata metadata_;
 
  100  utils::FixedArray<StubPtr> stubs_;
 
  103template <
typename Client>
 
  104ClientData& GetClientData(Client& client) {