9#include <unordered_map> 
   11#include <userver/concurrent/striped_counter.hpp> 
   12#include <userver/utils/fast_pimpl.hpp> 
   14USERVER_NAMESPACE_BEGIN
 
   22class ResponseDataAccounter 
final {
 
   24  void StartRequest(size_t size,
 
   25                    std::chrono::steady_clock::time_point create_time);
 
   27  void StopRequest(size_t size,
 
   28                   std::chrono::steady_clock::time_point create_time);
 
   30  size_t GetCurrentLevel() 
const { 
return current_; }
 
   32  size_t GetMaxLevel() 
const { 
return max_; }
 
   34  void SetMaxLevel(size_t size) { max_ = size; }
 
   36  std::chrono::milliseconds GetAvgRequestTime() 
const;
 
   39  std::atomic<size_t> current_{0};
 
   40  std::atomic<size_t> max_{std::numeric_limits<size_t>::max()};
 
   48  explicit ResponseBase(ResponseDataAccounter& data_accounter);
 
   51  virtual ~ResponseBase() 
noexcept;
 
   53  void SetData(std::string data);
 
   54  const std::string& GetData() 
const { 
return data_; }
 
   56  virtual bool IsBodyStreamed() 
const = 0;
 
   57  virtual bool WaitForHeadersEnd() = 0;
 
   58  virtual void SetHeadersEnd() = 0;
 
   63  void SetReady(std::chrono::steady_clock::time_point now);
 
   64  virtual void SetSendFailed(
 
   65      std::chrono::steady_clock::time_point failure_time);
 
   66  bool IsLimitReached() 
const;
 
   68  bool IsReady() 
const { 
return is_ready_; }
 
   69  bool IsSent() 
const { 
return is_sent_; }
 
   70  size_t BytesSent() 
const { 
return bytes_sent_; }
 
   71  std::chrono::steady_clock::time_point ReadyTime() 
const {
 
   74  std::chrono::steady_clock::time_point SentTime() 
const { 
return sent_time_; }
 
   76  virtual void SendResponse(engine::
io::
RwBase& socket) = 0;
 
   78  virtual void SetStatusServiceUnavailable() = 0;
 
   79  virtual void SetStatusOk() = 0;
 
   80  virtual void SetStatusNotFound() = 0;
 
   84  ResponseBase(ResponseDataAccounter& data_account,
 
   85               std::chrono::steady_clock::time_point now);
 
   87  void SetSent(std::size_t bytes_sent,
 
   88               std::chrono::steady_clock::time_point sent_time);
 
   93    Guard(ResponseDataAccounter& accounter,
 
   94          std::chrono::steady_clock::time_point create_time, size_t size)
 
   95        : accounter_(accounter), create_time_(create_time), size_(size) {
 
   96      accounter_.StartRequest(size_, create_time_);
 
   99    ~Guard() { accounter_.StopRequest(size_, create_time_); }
 
  102    ResponseDataAccounter& accounter_;
 
  103    std::chrono::steady_clock::time_point create_time_;
 
  107  ResponseDataAccounter& accounter_;
 
  108  std::optional<Guard> guard_;
 
  110  std::chrono::steady_clock::time_point create_time_;
 
  111  std::chrono::steady_clock::time_point ready_time_;
 
  112  std::chrono::steady_clock::time_point sent_time_;
 
  113  size_t bytes_sent_ = 0;
 
  114  bool is_ready_ = 
false;
 
  115  bool is_sent_ = 
false;