userver: userver/storages/redis/request_evalsha.hpp Source File
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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) : request_(std::move(request)) {}
24
25 /// Wait for the request to finish on Redis server
26 void Wait() { request_.Wait(); }
27
28 /// Ignore the query result and do not wait for the Redis server to finish executing it
29 void IgnoreResult() const { request_.IgnoreResult(); }
30
31 /// Wait for the request to finish on Redis server and get the result
32 EvalShaResult Get(const std::string& request_description = {}) {
33 auto reply_ptr = request_.GetRaw();
34 const auto& reply_data = reply_ptr->data;
35 if (reply_data.IsError()) {
36 const auto& msg = reply_data.GetError();
37 if (msg.find("NOSCRIPT", 0) == 0) {
38 return EvalShaResult(true);
39 }
40 }
41 /// no error try treat as usual eval
42 return impl::ParseReply<ScriptResult, ReplyType>(std::move(reply_ptr), request_description);
43 }
44
45private:
46 RequestEvalShaCommon request_;
47};
48
49/// @brief Value, returned by storages::redis::RequestEvalSha.
50template <typename ReplyType>
51class EvalShaResult final {
52public:
53 /// @return true iff the script does not exist on the Redis shard
54 bool IsNoScriptError() const noexcept { return no_script_error_; }
55
56 /// @return true iff the script does exist on the Redis shard and returned value
57 bool HasValue() const noexcept { return reply_.has_value(); }
58
59 /// Retrieve the value or throw an exception if there's no value
60 const ReplyType& Get() const { return reply_.value(); }
61
62 /// Retrieve the value or throws an exception if there's no value
63 ReplyType Extract() { return std::move(reply_).value(); }
64
65private:
66 template <typename, typename>
67 friend class RequestEvalSha;
68
69 EvalShaResult() = default;
70 explicit EvalShaResult(bool no_script) : no_script_error_{no_script} {}
71 EvalShaResult(ReplyType&& reply) : reply_(std::move(reply)) {}
72 std::optional<ReplyType> reply_;
73 bool no_script_error_ = false;
74};
75
76} // namespace storages::redis
77
78USERVER_NAMESPACE_END