userver: userver/storages/redis/request_evalsha.hpp Source File
Loading...
Searching...
No Matches
request_evalsha.hpp
1#pragma once
2
3#include <boost/algorithm/string/predicate.hpp>
4#include <userver/storages/redis/parse_reply.hpp>
5#include <userver/storages/redis/reply.hpp>
6#include <userver/storages/redis/request.hpp>
7
8USERVER_NAMESPACE_BEGIN
9
10namespace storages::redis {
11
12template <typename ScriptResult, typename ReplyType = ScriptResult>
13class [[nodiscard]] RequestEvalSha final {
14 public:
15 class EvalShaResult final {
16 public:
17 bool IsNoScriptError() const { return no_script_error_; }
18 bool HasValue() const { return reply_.has_value(); }
19 const ReplyType& Get() const { return *reply_; }
20 ReplyType Extract() { return std::move(*reply_); }
21
22 private:
23 friend class RequestEvalSha;
24 EvalShaResult() = default;
25 explicit EvalShaResult(bool no_script) : no_script_error_{no_script} {}
26 EvalShaResult(ReplyType&& reply) : reply_(std::move(reply)) {}
27 std::optional<ReplyType> reply_;
28 bool no_script_error_ = false;
29 };
30
31 explicit RequestEvalSha(RequestEvalShaCommon&& request)
32 : request_(std::move(request)) {}
33
34 void Wait() { request_.Wait(); }
35
36 void IgnoreResult() const { request_.IgnoreResult(); }
37
38 EvalShaResult Get(const std::string& request_description = {}) {
39 auto reply_ptr = request_.GetRaw();
40 const auto& reply_data = reply_ptr->data;
41 if (reply_data.IsError()) {
42 const auto& msg = reply_data.GetError();
43 if (boost::starts_with(msg, "NOSCRIPT")) {
44 return EvalShaResult(true);
45 }
46 }
47 /// no error try treat as usual eval
48 return ParseReply<ScriptResult, ReplyType>(std::move(reply_ptr),
49 request_description);
50 }
51
52 private:
53 RequestEvalShaCommon request_;
54};
55
56} // namespace storages::redis
57
58USERVER_NAMESPACE_END