28#include <userver/storages/redis/client.hpp> 
   29#include <userver/storages/redis/command_control.hpp> 
   30#include <userver/utils/hedged_request.hpp> 
   32USERVER_NAMESPACE_BEGIN
 
   37template <
typename RedisRequestType>
 
   38struct RedisRequestStrategy {
 
   40  using RequestType = RedisRequestType;
 
   41  using ReplyType = RequestType::Reply;
 
   42  using GenF = std::function<std::optional<RequestType>(
int)>;
 
   44  explicit RedisRequestStrategy(GenF gen_callback)
 
   45      : gen_callback_(std::move(gen_callback)) {}
 
   47  RedisRequestStrategy(RedisRequestStrategy&& other) 
noexcept = 
default;
 
   51  std::optional<RequestType> Create(size_t try_count) {
 
   52    return gen_callback_(try_count);
 
   54  std::optional<std::chrono::milliseconds> ProcessReply(RequestType&& request) {
 
   55    reply_ = std::move(request).Get();
 
   58  std::optional<ReplyType> ExtractReply() { 
return std::move(reply_); }
 
   59  void Finish(RequestType&&) {}
 
   64  std::optional<ReplyType> reply_;
 
   69template <
typename RedisRequestType>
 
   71    impl::RedisRequestStrategy<RedisRequestType>>;
 
   73template <
typename RedisRequestType, 
typename... Args,
 
   74          typename M = RedisRequestType (storages::redis::Client::*)(
 
   81      [redis, method, cc{std::move(cc)},
 
   82       args_tuple{std::tuple(std::move(args)...)}](
 
   83          int try_count) 
mutable -> std::optional<RedisRequestType> {
 
   84    cc.retry_counter = try_count;
 
   88        [redis, method, cc](
auto&&... args) {
 
   89          return (redis.get()->*method)(args..., cc);
 
   93  return utils::hedging::HedgeRequestAsync(
 
   94      impl::RedisRequestStrategy<RedisRequestType>(std::move(gen_request)),
 
   98template <
typename RedisRequestType>
 
  100    impl::RedisRequestStrategy<RedisRequestType>>;
 
  102template <
typename RedisRequestType, 
typename... Args,
 
  103          typename M = RedisRequestType (storages::redis::Client::*)(
 
  110      [redis, method, cc{std::move(cc)},
 
  111       args_tuple{std::tuple(std::move(args)...)}](
 
  112          int try_count) 
mutable -> std::optional<RedisRequestType> {
 
  113    cc.retry_counter = try_count;
 
  117        [redis, method, cc](
auto&&... args) {
 
  118          return (redis.get()->*method)(args..., cc);
 
  122  return utils::hedging::HedgeRequest(
 
  123      impl::RedisRequestStrategy<RedisRequestType>(std::move(gen_request)),