userver: userver/storages/redis/request_evalsha.hpp Source File
Loading...
Searching...
No Matches
request_evalsha.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief @copybrief storages::redis::RequestEvalSha
5
6#include <userver/storages/redis/parse_reply.hpp>
7#include <userver/storages/redis/reply.hpp>
8#include <userver/storages/redis/request.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace storages::redis {
13
14template <typename ReplyType>
15class EvalShaResult;
16
17/// @brief Redis future for EVALSHA responses.
18template <typename ScriptResult, typename ReplyType = ScriptResult>
19class [[nodiscard]] RequestEvalSha final {
20public:
21 using EvalShaResult = storages::redis::EvalShaResult<ReplyType>;
22
23 explicit RequestEvalSha(RequestEvalShaCommon&& request)
24 : request_(std::move(request))
25 {}
26
27 /// Wait for the request to finish on Redis server
28 void Wait() { request_.Wait(); }
29
30 /// Ignore the query result and do not wait for the Redis server to finish executing it
31 void IgnoreResult() const { request_.IgnoreResult(); }
32
33 /// Wait for the request to finish on Redis server and get the result
34 EvalShaResult Get(const std::string& request_description = {}) {
35 auto reply_ptr = request_.GetRaw();
36 const auto& reply_data = reply_ptr->data;
37 if (reply_data.IsError()) {
38 const auto& msg = reply_data.GetError();
39 if (msg.find("NOSCRIPT", 0) == 0) {
40 return EvalShaResult(true);
41 }
42 }
43 /// no error try treat as usual eval
44 return impl::ParseReply<ScriptResult, ReplyType>(std::move(reply_ptr), request_description);
45 }
46
47private:
48 RequestEvalShaCommon request_;
49};
50
51/// @brief Value, returned by storages::redis::RequestEvalSha.
52template <typename ReplyType>
53class EvalShaResult final {
54public:
55 /// @return true iff the script does not exist on the Redis shard
56 bool IsNoScriptError() const noexcept { return no_script_error_; }
57
58 /// @return true iff the script does exist on the Redis shard and returned value
59 bool HasValue() const noexcept { return reply_.has_value(); }
60
61 /// Retrieve the value or throw an exception if there's no value
62 const ReplyType& Get() const { return reply_.value(); }
63
64 /// Retrieve the value or throws an exception if there's no value
65 ReplyType Extract() { return std::move(reply_).value(); }
66
67private:
68 template <typename, typename>
69 friend class RequestEvalSha;
70
71 EvalShaResult() = default;
72 explicit EvalShaResult(bool no_script)
73 : no_script_error_{no_script}
74 {}
75 EvalShaResult(ReplyType&& reply)
76 : reply_(std::move(reply))
77 {}
78 std::optional<ReplyType> reply_;
79 bool no_script_error_ = false;
80};
81
82} // namespace storages::redis
83
84USERVER_NAMESPACE_END