mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Adds automatic formatting with clang-format
This commit is contained in:
committed by
GitHub
parent
1060733b84
commit
328ad97a79
176
.clang-format
Normal file
176
.clang-format
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
ColumnLimit: 100
|
||||||
|
IndentWidth: 3
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
AccessModifierOffset: -3
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
AlignAfterOpenBracket: AlwaysBreak
|
||||||
|
PointerAlignment: Left
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<boost/redis.*>|<boost/redis/.*>'
|
||||||
|
Priority: -10
|
||||||
|
SortPriority: 1
|
||||||
|
- Regex: '^<boost/.*>'
|
||||||
|
Priority: -8
|
||||||
|
SortPriority: 3
|
||||||
|
- Regex: "^<.*"
|
||||||
|
Priority: -6
|
||||||
|
SortPriority: 5
|
||||||
|
- Regex: ".*"
|
||||||
|
Priority: -5
|
||||||
|
SortPriority: 4
|
||||||
|
IndentCaseLabels: true
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlignArrayOfStructures: Left
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
PenaltyBreakAssignment: 2000000
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 0
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyBreakScopeResolution: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200000000
|
||||||
|
|
||||||
|
# Defaults (based on Google)
|
||||||
|
AlignConsecutiveMacros: false
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: ExceptShortType
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BreakTemplateDeclarations: Leave
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
CommentPragmas: '(^ IWYU pragma:)|(^\\copydoc )|(^ ?\\n)'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 0
|
||||||
|
ContinuationIndentWidth: 3
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeIsMainRegex: null
|
||||||
|
IncludeIsMainSourceRegex: ""
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: ""
|
||||||
|
MacroBlockEnd: ""
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Never
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
RawStringFormats:
|
||||||
|
- Language: Cpp
|
||||||
|
Delimiters:
|
||||||
|
- cc
|
||||||
|
- CC
|
||||||
|
- cpp
|
||||||
|
- Cpp
|
||||||
|
- CPP
|
||||||
|
- "c++"
|
||||||
|
- "C++"
|
||||||
|
CanonicalDelimiter: ""
|
||||||
|
BasedOnStyle: google
|
||||||
|
- Language: TextProto
|
||||||
|
Delimiters:
|
||||||
|
- pb
|
||||||
|
- PB
|
||||||
|
- proto
|
||||||
|
- PROTO
|
||||||
|
EnclosingFunctions:
|
||||||
|
- EqualsProto
|
||||||
|
- EquivToProto
|
||||||
|
- PARSE_PARTIAL_TEXT_PROTO
|
||||||
|
- PARSE_TEST_PROTO
|
||||||
|
- PARSE_TEXT_PROTO
|
||||||
|
- ParseTextOrDie
|
||||||
|
- ParseTextProtoOrDie
|
||||||
|
CanonicalDelimiter: ""
|
||||||
|
BasedOnStyle: google
|
||||||
|
ReflowComments: false
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 8
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
AlignConsecutiveShortCaseStatements:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: true
|
||||||
|
AlignCaseColons: false
|
||||||
|
---
|
||||||
|
|
||||||
@@ -4,8 +4,9 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
@@ -63,5 +64,9 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#else // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
auto main() -> int {std::cout << "Requires coroutine support." << std::endl; return 1;}
|
auto main() -> int
|
||||||
|
{
|
||||||
|
std::cout << "Requires coroutine support." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/asio.hpp>
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
@@ -59,5 +60,9 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#else // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
auto main() -> int {std::cout << "Requires coroutine support." << std::endl; return 1;}
|
auto main() -> int
|
||||||
|
{
|
||||||
|
std::cout << "Requires coroutine support." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace asio = boost::asio;
|
namespace asio = boost::asio;
|
||||||
@@ -14,7 +16,7 @@ using boost::redis::request;
|
|||||||
using boost::redis::response;
|
using boost::redis::response;
|
||||||
using boost::redis::config;
|
using boost::redis::config;
|
||||||
|
|
||||||
auto main(int argc, char * argv[]) -> int
|
auto main(int argc, char* argv[]) -> int
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
config cfg;
|
config cfg;
|
||||||
@@ -47,4 +49,3 @@ auto main(int argc, char * argv[]) -> int
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
#include "sync_connection.hpp"
|
#include "sync_connection.hpp"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
using boost::redis::sync_connection;
|
using boost::redis::sync_connection;
|
||||||
using boost::redis::request;
|
using boost::redis::request;
|
||||||
using boost::redis::response;
|
using boost::redis::response;
|
||||||
using boost::redis::config;
|
using boost::redis::config;
|
||||||
|
|
||||||
auto main(int argc, char * argv[]) -> int
|
auto main(int argc, char* argv[]) -> int
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
config cfg;
|
config cfg;
|
||||||
|
|||||||
@@ -5,13 +5,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/asio/signal_set.hpp>
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
#include <boost/asio/redirect_error.hpp>
|
|
||||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||||
#include <unistd.h>
|
#include <boost/asio/redirect_error.hpp>
|
||||||
|
#include <boost/asio/signal_set.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
|
#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
|
||||||
@@ -38,8 +40,7 @@ using namespace std::chrono_literals;
|
|||||||
// Chat over Redis pubsub. To test, run this program from multiple
|
// Chat over Redis pubsub. To test, run this program from multiple
|
||||||
// terminals and type messages to stdin.
|
// terminals and type messages to stdin.
|
||||||
|
|
||||||
auto
|
auto receiver(std::shared_ptr<connection> conn) -> awaitable<void>
|
||||||
receiver(std::shared_ptr<connection> conn) -> awaitable<void>
|
|
||||||
{
|
{
|
||||||
request req;
|
request req;
|
||||||
req.push("SUBSCRIBE", "channel");
|
req.push("SUBSCRIBE", "channel");
|
||||||
@@ -48,7 +49,6 @@ receiver(std::shared_ptr<connection> conn) -> awaitable<void>
|
|||||||
conn->set_receive_response(resp);
|
conn->set_receive_response(resp);
|
||||||
|
|
||||||
while (conn->will_reconnect()) {
|
while (conn->will_reconnect()) {
|
||||||
|
|
||||||
// Subscribe to channels.
|
// Subscribe to channels.
|
||||||
co_await conn->async_exec(req, ignore);
|
co_await conn->async_exec(req, ignore);
|
||||||
|
|
||||||
@@ -57,18 +57,16 @@ receiver(std::shared_ptr<connection> conn) -> awaitable<void>
|
|||||||
co_await conn->async_receive(redirect_error(use_awaitable, ec));
|
co_await conn->async_receive(redirect_error(use_awaitable, ec));
|
||||||
if (ec)
|
if (ec)
|
||||||
break; // Connection lost, break so we can reconnect to channels.
|
break; // Connection lost, break so we can reconnect to channels.
|
||||||
std::cout
|
std::cout << resp.value().at(1).value << " " << resp.value().at(2).value << " "
|
||||||
<< resp.value().at(1).value
|
<< resp.value().at(3).value << std::endl;
|
||||||
<< " " << resp.value().at(2).value
|
|
||||||
<< " " << resp.value().at(3).value
|
|
||||||
<< std::endl;
|
|
||||||
resp.value().clear();
|
resp.value().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publishes stdin messages to a Redis channel.
|
// Publishes stdin messages to a Redis channel.
|
||||||
auto publisher(std::shared_ptr<stream_descriptor> in, std::shared_ptr<connection> conn) -> awaitable<void>
|
auto publisher(std::shared_ptr<stream_descriptor> in, std::shared_ptr<connection> conn)
|
||||||
|
-> awaitable<void>
|
||||||
{
|
{
|
||||||
for (std::string msg;;) {
|
for (std::string msg;;) {
|
||||||
auto n = co_await async_read_until(*in, dynamic_buffer(msg, 1024), "\n");
|
auto n = co_await async_read_until(*in, dynamic_buffer(msg, 1024), "\n");
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ using boost::asio::awaitable;
|
|||||||
using boost::asio::detached;
|
using boost::asio::detached;
|
||||||
using boost::asio::consign;
|
using boost::asio::consign;
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
std::ostream& operator<<(std::ostream& os, std::optional<T> const& opt)
|
std::ostream& operator<<(std::ostream& os, std::optional<T> const& opt)
|
||||||
{
|
{
|
||||||
if (opt.has_value())
|
if (opt.has_value())
|
||||||
@@ -37,25 +39,28 @@ std::ostream& operator<<(std::ostream& os, std::optional<T> const& opt)
|
|||||||
|
|
||||||
void print(std::map<std::string, std::string> const& cont)
|
void print(std::map<std::string, std::string> const& cont)
|
||||||
{
|
{
|
||||||
for (auto const& e: cont)
|
for (auto const& e : cont)
|
||||||
std::cout << e.first << ": " << e.second << "\n";
|
std::cout << e.first << ": " << e.second << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void print(std::vector<T> const& cont)
|
void print(std::vector<T> const& cont)
|
||||||
{
|
{
|
||||||
for (auto const& e: cont) std::cout << e << " ";
|
for (auto const& e : cont)
|
||||||
|
std::cout << e << " ";
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stores the content of some STL containers in Redis.
|
// Stores the content of some STL containers in Redis.
|
||||||
auto store(std::shared_ptr<connection> conn) -> awaitable<void>
|
auto store(std::shared_ptr<connection> conn) -> awaitable<void>
|
||||||
{
|
{
|
||||||
std::vector<int> vec
|
std::vector<int> vec{1, 2, 3, 4, 5, 6};
|
||||||
{1, 2, 3, 4, 5, 6};
|
|
||||||
|
|
||||||
std::map<std::string, std::string> map
|
std::map<std::string, std::string> map{
|
||||||
{{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
|
{"key1", "value1"},
|
||||||
|
{"key2", "value2"},
|
||||||
|
{"key3", "value3"}
|
||||||
|
};
|
||||||
|
|
||||||
request req;
|
request req;
|
||||||
req.push_range("RPUSH", "rpush-key", vec);
|
req.push_range("RPUSH", "rpush-key", vec);
|
||||||
@@ -113,9 +118,9 @@ auto transaction(std::shared_ptr<connection> conn) -> awaitable<void>
|
|||||||
response<
|
response<
|
||||||
std::optional<std::vector<int>>,
|
std::optional<std::vector<int>>,
|
||||||
std::optional<std::map<std::string, std::string>>,
|
std::optional<std::map<std::string, std::string>>,
|
||||||
std::optional<std::vector<std::optional<std::string>>>
|
std::optional<std::vector<std::optional<std::string>>>> // exec
|
||||||
> // exec
|
>
|
||||||
> resp;
|
resp;
|
||||||
|
|
||||||
co_await conn->async_exec(req, resp);
|
co_await conn->async_exec(req, resp);
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/asio/signal_set.hpp>
|
|
||||||
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
#include <boost/asio/redirect_error.hpp>
|
#include <boost/asio/redirect_error.hpp>
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/signal_set.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
@@ -22,10 +24,8 @@ using boost::system::error_code;
|
|||||||
using boost::redis::connection;
|
using boost::redis::connection;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
auto
|
auto echo_server_session(asio::ip::tcp::socket socket, std::shared_ptr<connection> conn)
|
||||||
echo_server_session(
|
-> asio::awaitable<void>
|
||||||
asio::ip::tcp::socket socket,
|
|
||||||
std::shared_ptr<connection> conn) -> asio::awaitable<void>
|
|
||||||
{
|
{
|
||||||
request req;
|
request req;
|
||||||
response<std::string> resp;
|
response<std::string> resp;
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/consign.hpp>
|
#include <boost/asio/consign.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/consign.hpp>
|
#include <boost/asio/consign.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|||||||
@@ -5,20 +5,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/describe.hpp>
|
|
||||||
#include <boost/asio/consign.hpp>
|
#include <boost/asio/consign.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
#include <string>
|
#include <boost/describe.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|
||||||
#include <boost/json/serialize.hpp>
|
#include <boost/redis/resp3/serialization.hpp>
|
||||||
|
|
||||||
#include <boost/json/parse.hpp>
|
#include <boost/json/parse.hpp>
|
||||||
|
#include <boost/json/serialize.hpp>
|
||||||
#include <boost/json/value_from.hpp>
|
#include <boost/json/value_from.hpp>
|
||||||
#include <boost/json/value_to.hpp>
|
#include <boost/json/value_to.hpp>
|
||||||
#include <boost/redis/resp3/serialization.hpp>
|
|
||||||
|
|
||||||
namespace asio = boost::asio;
|
namespace asio = boost::asio;
|
||||||
namespace resp3 = boost::redis::resp3;
|
namespace resp3 = boost::redis::resp3;
|
||||||
@@ -46,11 +49,7 @@ void boost_redis_to_bulk(std::string& to, user const& u)
|
|||||||
resp3::boost_redis_to_bulk(to, boost::json::serialize(boost::json::value_from(u)));
|
resp3::boost_redis_to_bulk(to, boost::json::serialize(boost::json::value_from(u)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void boost_redis_from_bulk(user& u, node_view const& node, boost::system::error_code&)
|
||||||
boost_redis_from_bulk(
|
|
||||||
user& u,
|
|
||||||
node_view const& node,
|
|
||||||
boost::system::error_code&)
|
|
||||||
{
|
{
|
||||||
u = boost::json::value_to<user>(boost::json::parse(node.value));
|
u = boost::json::value_to<user>(boost::json::parse(node.value));
|
||||||
}
|
}
|
||||||
@@ -75,8 +74,7 @@ auto co_main(config cfg) -> asio::awaitable<void>
|
|||||||
conn->cancel();
|
conn->cancel();
|
||||||
|
|
||||||
// Prints the first ping
|
// Prints the first ping
|
||||||
std::cout
|
std::cout << "Name: " << std::get<1>(resp).value().name << "\n"
|
||||||
<< "Name: " << std::get<1>(resp).value().name << "\n"
|
|
||||||
<< "Age: " << std::get<1>(resp).value().age << "\n"
|
<< "Age: " << std::get<1>(resp).value().age << "\n"
|
||||||
<< "Country: " << std::get<1>(resp).value().country << "\n";
|
<< "Country: " << std::get<1>(resp).value().country << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/resp3/serialization.hpp>
|
#include <boost/redis/resp3/serialization.hpp>
|
||||||
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/consign.hpp>
|
#include <boost/asio/consign.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// See the definition in person.proto. This header is automatically
|
// See the definition in person.proto. This header is automatically
|
||||||
@@ -32,8 +34,7 @@ using boost::redis::resp3::node_view;
|
|||||||
using tutorial::person;
|
using tutorial::person;
|
||||||
|
|
||||||
// Boost.Redis customization points (example/protobuf.hpp)
|
// Boost.Redis customization points (example/protobuf.hpp)
|
||||||
namespace tutorial
|
namespace tutorial {
|
||||||
{
|
|
||||||
|
|
||||||
// Below I am using a Boost.Redis to indicate a protobuf error, this
|
// Below I am using a Boost.Redis to indicate a protobuf error, this
|
||||||
// is ok for an example, users however might want to define their own
|
// is ok for an example, users however might want to define their own
|
||||||
@@ -47,18 +48,14 @@ void boost_redis_to_bulk(std::string& to, person const& u)
|
|||||||
resp3::boost_redis_to_bulk(to, tmp);
|
resp3::boost_redis_to_bulk(to, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void boost_redis_from_bulk(person& u, node_view const& node, boost::system::error_code& ec)
|
||||||
boost_redis_from_bulk(
|
|
||||||
person& u,
|
|
||||||
node_view const& node,
|
|
||||||
boost::system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
std::string const tmp {node.value};
|
std::string const tmp{node.value};
|
||||||
if (!u.ParseFromString(tmp))
|
if (!u.ParseFromString(tmp))
|
||||||
ec = boost::redis::error::invalid_data_type;
|
ec = boost::redis::error::invalid_data_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // tutorial
|
} // namespace tutorial
|
||||||
|
|
||||||
using tutorial::boost_redis_to_bulk;
|
using tutorial::boost_redis_to_bulk;
|
||||||
using tutorial::boost_redis_from_bulk;
|
using tutorial::boost_redis_from_bulk;
|
||||||
@@ -84,8 +81,7 @@ asio::awaitable<void> co_main(config cfg)
|
|||||||
co_await conn->async_exec(req, resp);
|
co_await conn->async_exec(req, resp);
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
|
|
||||||
std::cout
|
std::cout << "Name: " << std::get<1>(resp).value().name() << "\n"
|
||||||
<< "Name: " << std::get<1>(resp).value().name() << "\n"
|
|
||||||
<< "Age: " << std::get<1>(resp).value().id() << "\n"
|
<< "Age: " << std::get<1>(resp).value().id() << "\n"
|
||||||
<< "Email: " << std::get<1>(resp).value().email() << "\n";
|
<< "Email: " << std::get<1>(resp).value().email() << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
|
||||||
#include <boost/asio/redirect_error.hpp>
|
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/asio/redirect_error.hpp>
|
||||||
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
@@ -21,8 +23,7 @@ using boost::redis::config;
|
|||||||
using boost::redis::address;
|
using boost::redis::address;
|
||||||
using boost::redis::connection;
|
using boost::redis::connection;
|
||||||
|
|
||||||
auto redir(boost::system::error_code& ec)
|
auto redir(boost::system::error_code& ec) { return asio::redirect_error(asio::use_awaitable, ec); }
|
||||||
{ return asio::redirect_error(asio::use_awaitable, ec); }
|
|
||||||
|
|
||||||
// For more info see
|
// For more info see
|
||||||
// - https://redis.io/docs/manual/sentinel.
|
// - https://redis.io/docs/manual/sentinel.
|
||||||
@@ -48,7 +49,9 @@ auto resolve_master_address(std::vector<address> const& addresses) -> asio::awai
|
|||||||
conn->cancel();
|
conn->cancel();
|
||||||
conn->reset_stream();
|
conn->reset_stream();
|
||||||
if (!ec && std::get<0>(resp))
|
if (!ec && std::get<0>(resp))
|
||||||
co_return address{std::get<0>(resp).value().value().at(0), std::get<0>(resp).value().value().at(1)};
|
co_return address{
|
||||||
|
std::get<0>(resp).value().value().at(0),
|
||||||
|
std::get<0>(resp).value().value().at(1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
co_return address{};
|
co_return address{};
|
||||||
@@ -58,16 +61,15 @@ auto co_main(config cfg) -> asio::awaitable<void>
|
|||||||
{
|
{
|
||||||
// A list of sentinel addresses from which only one is responsive.
|
// A list of sentinel addresses from which only one is responsive.
|
||||||
// This simulates sentinels that are down.
|
// This simulates sentinels that are down.
|
||||||
std::vector<address> const addresses
|
std::vector<address> const addresses{
|
||||||
{ address{"foo", "26379"}
|
address{"foo", "26379"},
|
||||||
, address{"bar", "26379"}
|
address{"bar", "26379"},
|
||||||
, cfg.addr
|
cfg.addr
|
||||||
};
|
};
|
||||||
|
|
||||||
auto const ep = co_await resolve_master_address(addresses);
|
auto const ep = co_await resolve_master_address(addresses);
|
||||||
|
|
||||||
std::clog
|
std::clog << "Host: " << ep.host << "\n"
|
||||||
<< "Host: " << ep.host << "\n"
|
|
||||||
<< "Port: " << ep.port << "\n"
|
<< "Port: " << ep.port << "\n"
|
||||||
<< std::flush;
|
<< std::flush;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/asio/co_spawn.hpp>
|
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/consign.hpp>
|
|
||||||
#include <boost/asio/signal_set.hpp>
|
|
||||||
#include <boost/asio/awaitable.hpp>
|
#include <boost/asio/awaitable.hpp>
|
||||||
|
#include <boost/asio/co_spawn.hpp>
|
||||||
|
#include <boost/asio/consign.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/asio/signal_set.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
@@ -63,10 +65,8 @@ auto stream_reader(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
|||||||
// The streamId is located at item_index - 2
|
// The streamId is located at item_index - 2
|
||||||
// The payload is located at item_index + 1
|
// The payload is located at item_index + 1
|
||||||
stream_id = resp.value().at(item_index - 2).value;
|
stream_id = resp.value().at(item_index - 2).value;
|
||||||
std::cout
|
std::cout << "StreamId: " << stream_id << ", "
|
||||||
<< "StreamId: " << stream_id << ", "
|
<< "MyField: " << resp.value().at(item_index + 1).value << std::endl;
|
||||||
<< "MyField: " << resp.value().at(item_index + 1).value
|
|
||||||
<< std::endl;
|
|
||||||
++item_index; // We can increase so we don't read this again
|
++item_index; // We can increase so we don't read this again
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,15 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
|
|
||||||
#include <boost/asio/awaitable.hpp>
|
#include <boost/asio/awaitable.hpp>
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/consign.hpp>
|
#include <boost/asio/consign.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
#include <boost/asio/redirect_error.hpp>
|
#include <boost/asio/redirect_error.hpp>
|
||||||
#include <boost/asio/signal_set.hpp>
|
#include <boost/asio/signal_set.hpp>
|
||||||
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
@@ -47,8 +49,7 @@ using asio::signal_set;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Receives server pushes.
|
// Receives server pushes.
|
||||||
auto
|
auto receiver(std::shared_ptr<connection> conn) -> asio::awaitable<void>
|
||||||
receiver(std::shared_ptr<connection> conn) -> asio::awaitable<void>
|
|
||||||
{
|
{
|
||||||
request req;
|
request req;
|
||||||
req.push("SUBSCRIBE", "channel");
|
req.push("SUBSCRIBE", "channel");
|
||||||
@@ -58,7 +59,6 @@ receiver(std::shared_ptr<connection> conn) -> asio::awaitable<void>
|
|||||||
|
|
||||||
// Loop while reconnection is enabled
|
// Loop while reconnection is enabled
|
||||||
while (conn->will_reconnect()) {
|
while (conn->will_reconnect()) {
|
||||||
|
|
||||||
// Reconnect to the channels.
|
// Reconnect to the channels.
|
||||||
co_await conn->async_exec(req, ignore);
|
co_await conn->async_exec(req, ignore);
|
||||||
|
|
||||||
@@ -74,11 +74,8 @@ receiver(std::shared_ptr<connection> conn) -> asio::awaitable<void>
|
|||||||
if (ec)
|
if (ec)
|
||||||
break; // Connection lost, break so we can reconnect to channels.
|
break; // Connection lost, break so we can reconnect to channels.
|
||||||
|
|
||||||
std::cout
|
std::cout << resp.value().at(1).value << " " << resp.value().at(2).value << " "
|
||||||
<< resp.value().at(1).value
|
<< resp.value().at(3).value << std::endl;
|
||||||
<< " " << resp.value().at(2).value
|
|
||||||
<< " " << resp.value().at(3).value
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
consume_one(resp);
|
consume_one(resp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
|
||||||
#include <boost/redis/config.hpp>
|
#include <boost/redis/config.hpp>
|
||||||
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace asio = boost::asio;
|
namespace asio = boost::asio;
|
||||||
@@ -19,7 +21,7 @@ using boost::redis::logger;
|
|||||||
|
|
||||||
extern asio::awaitable<void> co_main(config);
|
extern asio::awaitable<void> co_main(config);
|
||||||
|
|
||||||
auto main(int argc, char * argv[]) -> int
|
auto main(int argc, char* argv[]) -> int
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
config cfg;
|
config cfg;
|
||||||
|
|||||||
@@ -7,16 +7,17 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/request.hpp>
|
#include <boost/redis/request.hpp>
|
||||||
|
|
||||||
#include <boost/asio/deferred.hpp>
|
#include <boost/asio/deferred.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
#include <boost/asio/use_future.hpp>
|
#include <boost/asio/use_future.hpp>
|
||||||
#include <thread>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
class sync_connection {
|
class sync_connection {
|
||||||
public:
|
public:
|
||||||
@@ -25,10 +26,7 @@ public:
|
|||||||
, conn_{std::make_shared<connection>(ioc_)}
|
, conn_{std::make_shared<connection>(ioc_)}
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~sync_connection()
|
~sync_connection() { thread_.join(); }
|
||||||
{
|
|
||||||
thread_.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void run(config cfg)
|
void run(config cfg)
|
||||||
{
|
{
|
||||||
@@ -42,16 +40,18 @@ public:
|
|||||||
|
|
||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
asio::dispatch(ioc_, [this]() { conn_->cancel(); });
|
asio::dispatch(ioc_, [this]() {
|
||||||
|
conn_->cancel();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Response>
|
template <class Response>
|
||||||
auto exec(request const& req, Response& resp)
|
auto exec(request const& req, Response& resp)
|
||||||
{
|
{
|
||||||
asio::dispatch(
|
asio::dispatch(conn_->get_executor(), asio::deferred([this, &req, &resp]() {
|
||||||
conn_->get_executor(),
|
return conn_->async_exec(req, resp, asio::deferred);
|
||||||
asio::deferred([this, &req, &resp]() { return conn_->async_exec(req, resp, asio::deferred); }))
|
}))(asio::use_future)
|
||||||
(asio::use_future).get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -60,4 +60,4 @@ private:
|
|||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace boost::redis
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
#define BOOST_REDIS_HPP
|
#define BOOST_REDIS_HPP
|
||||||
|
|
||||||
#include <boost/redis/config.hpp>
|
#include <boost/redis/config.hpp>
|
||||||
#include <boost/redis/error.hpp>
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/request.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
#include <boost/redis/response.hpp>
|
|
||||||
#include <boost/redis/ignore.hpp>
|
#include <boost/redis/ignore.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
|
#include <boost/redis/request.hpp>
|
||||||
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
/** @defgroup high-level-api Reference
|
/** @defgroup high-level-api Reference
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,20 +7,20 @@
|
|||||||
#ifndef BOOST_REDIS_ADAPTER_ADAPT_HPP
|
#ifndef BOOST_REDIS_ADAPTER_ADAPT_HPP
|
||||||
#define BOOST_REDIS_ADAPTER_ADAPT_HPP
|
#define BOOST_REDIS_ADAPTER_ADAPT_HPP
|
||||||
|
|
||||||
|
#include <boost/redis/adapter/detail/response_traits.hpp>
|
||||||
|
#include <boost/redis/adapter/detail/result_traits.hpp>
|
||||||
#include <boost/redis/resp3/node.hpp>
|
#include <boost/redis/resp3/node.hpp>
|
||||||
#include <boost/redis/response.hpp>
|
#include <boost/redis/response.hpp>
|
||||||
#include <boost/redis/adapter/detail/result_traits.hpp>
|
|
||||||
#include <boost/redis/adapter/detail/response_traits.hpp>
|
|
||||||
#include <boost/mp11.hpp>
|
#include <boost/mp11.hpp>
|
||||||
#include <boost/system.hpp>
|
#include <boost/system.hpp>
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <tuple>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
namespace boost::redis::adapter
|
namespace boost::redis::adapter {
|
||||||
{
|
|
||||||
|
|
||||||
/** @brief Adapts a type to be used as a response.
|
/** @brief Adapts a type to be used as a response.
|
||||||
*
|
*
|
||||||
@@ -34,7 +34,7 @@ namespace boost::redis::adapter
|
|||||||
*
|
*
|
||||||
* @param t Tuple containing the responses.
|
* @param t Tuple containing the responses.
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template <class T>
|
||||||
auto boost_redis_adapt(T& t) noexcept
|
auto boost_redis_adapt(T& t) noexcept
|
||||||
{
|
{
|
||||||
return detail::response_traits<T>::adapt(t);
|
return detail::response_traits<T>::adapt(t);
|
||||||
@@ -71,10 +71,12 @@ auto boost_redis_adapt(T& t) noexcept
|
|||||||
* co_await resp3::async_read(socket, dynamic_buffer(buffer), adapt(execs));
|
* co_await resp3::async_read(socket, dynamic_buffer(buffer), adapt(execs));
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template <class T>
|
||||||
auto adapt2(T& t = redis::ignore) noexcept
|
auto adapt2(T& t = redis::ignore) noexcept
|
||||||
{ return detail::result_traits<T>::adapt(t); }
|
{
|
||||||
|
return detail::result_traits<T>::adapt(t);
|
||||||
|
}
|
||||||
|
|
||||||
} // boost::redis::adapter
|
} // namespace boost::redis::adapter
|
||||||
|
|
||||||
#endif // BOOST_REDIS_ADAPTER_ADAPT_HPP
|
#endif // BOOST_REDIS_ADAPTER_ADAPT_HPP
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
#ifndef BOOST_REDIS_ANY_ADAPTER_HPP
|
#ifndef BOOST_REDIS_ANY_ADAPTER_HPP
|
||||||
#define BOOST_REDIS_ANY_ADAPTER_HPP
|
#define BOOST_REDIS_ANY_ADAPTER_HPP
|
||||||
|
|
||||||
|
|
||||||
#include <boost/redis/resp3/node.hpp>
|
|
||||||
#include <boost/redis/adapter/adapt.hpp>
|
#include <boost/redis/adapter/adapt.hpp>
|
||||||
|
#include <boost/redis/resp3/node.hpp>
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@@ -46,7 +47,7 @@ public:
|
|||||||
using namespace boost::redis::adapter;
|
using namespace boost::redis::adapter;
|
||||||
auto adapter = boost_redis_adapt(resp);
|
auto adapter = boost_redis_adapt(resp);
|
||||||
std::size_t size = adapter.get_supported_response_size();
|
std::size_t size = adapter.get_supported_response_size();
|
||||||
return { std::move(adapter), size };
|
return {std::move(adapter), size};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Executor>
|
template <class Executor>
|
||||||
@@ -63,9 +64,11 @@ public:
|
|||||||
* while `*this` is being used.
|
* while `*this` is being used.
|
||||||
*/
|
*/
|
||||||
template <class T, class = std::enable_if_t<!std::is_same_v<T, any_adapter>>>
|
template <class T, class = std::enable_if_t<!std::is_same_v<T, any_adapter>>>
|
||||||
explicit any_adapter(T& resp) : impl_(create_impl(resp)) {}
|
explicit any_adapter(T& resp)
|
||||||
|
: impl_(create_impl(resp))
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -7,27 +7,28 @@
|
|||||||
#ifndef BOOST_REDIS_ADAPTER_ADAPTERS_HPP
|
#ifndef BOOST_REDIS_ADAPTER_ADAPTERS_HPP
|
||||||
#define BOOST_REDIS_ADAPTER_ADAPTERS_HPP
|
#define BOOST_REDIS_ADAPTER_ADAPTERS_HPP
|
||||||
|
|
||||||
#include <boost/redis/error.hpp>
|
|
||||||
#include <boost/redis/resp3/type.hpp>
|
|
||||||
#include <boost/redis/resp3/serialization.hpp>
|
|
||||||
#include <boost/redis/resp3/node.hpp>
|
|
||||||
#include <boost/redis/adapter/result.hpp>
|
#include <boost/redis/adapter/result.hpp>
|
||||||
|
#include <boost/redis/error.hpp>
|
||||||
|
#include <boost/redis/resp3/node.hpp>
|
||||||
|
#include <boost/redis/resp3/serialization.hpp>
|
||||||
|
#include <boost/redis/resp3/type.hpp>
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <optional>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <forward_list>
|
|
||||||
#include <system_error>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <list>
|
|
||||||
#include <deque>
|
|
||||||
#include <vector>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string_view>
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
#include <deque>
|
||||||
|
#include <forward_list>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
|
#include <string_view>
|
||||||
|
#include <system_error>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// See https://stackoverflow.com/a/31658120/1077832
|
// See https://stackoverflow.com/a/31658120/1077832
|
||||||
#ifdef _LIBCPP_VERSION
|
#ifdef _LIBCPP_VERSION
|
||||||
@@ -35,60 +36,46 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace boost::redis::adapter::detail
|
namespace boost::redis::adapter::detail {
|
||||||
{
|
|
||||||
|
|
||||||
// Exclude bools, char and charXY_t types
|
// Exclude bools, char and charXY_t types
|
||||||
template <class T> struct is_integral_number : std::is_integral<T> {};
|
template <class T> struct is_integral_number : std::is_integral<T> { };
|
||||||
template <> struct is_integral_number<bool> : std::false_type {};
|
template <> struct is_integral_number<bool> : std::false_type { };
|
||||||
template <> struct is_integral_number<char> : std::false_type {};
|
template <> struct is_integral_number<char> : std::false_type { };
|
||||||
template <> struct is_integral_number<char16_t> : std::false_type {};
|
template <> struct is_integral_number<char16_t> : std::false_type { };
|
||||||
template <> struct is_integral_number<char32_t> : std::false_type {};
|
template <> struct is_integral_number<char32_t> : std::false_type { };
|
||||||
template <> struct is_integral_number<wchar_t> : std::false_type {};
|
template <> struct is_integral_number<wchar_t> : std::false_type { };
|
||||||
#ifdef __cpp_char8_t
|
#ifdef __cpp_char8_t
|
||||||
template <> struct is_integral_number<char8_t> : std::false_type {};
|
template <> struct is_integral_number<char8_t> : std::false_type { };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class T, bool = is_integral_number<T>::value>
|
template <class T, bool = is_integral_number<T>::value>
|
||||||
struct converter;
|
struct converter;
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
struct converter<T, true> {
|
struct converter<T, true> {
|
||||||
template <class String>
|
template <class String>
|
||||||
static void
|
static void apply(T& i, resp3::basic_node<String> const& node, system::error_code& ec)
|
||||||
apply(
|
|
||||||
T& i,
|
|
||||||
resp3::basic_node<String> const& node,
|
|
||||||
system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
auto const res =
|
auto const res = std::from_chars(node.value.data(), node.value.data() + node.value.size(), i);
|
||||||
std::from_chars(node.value.data(), node.value.data() + node.value.size(), i);
|
|
||||||
if (res.ec != std::errc())
|
if (res.ec != std::errc())
|
||||||
ec = redis::error::not_a_number;
|
ec = redis::error::not_a_number;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct converter<bool, false> {
|
struct converter<bool, false> {
|
||||||
template <class String>
|
template <class String>
|
||||||
static void
|
static void apply(bool& t, resp3::basic_node<String> const& node, system::error_code& ec)
|
||||||
apply(
|
|
||||||
bool& t,
|
|
||||||
resp3::basic_node<String> const& node,
|
|
||||||
system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
t = *node.value.data() == 't';
|
t = *node.value.data() == 't';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct converter<double, false> {
|
struct converter<double, false> {
|
||||||
template <class String>
|
template <class String>
|
||||||
static void
|
static void apply(double& d, resp3::basic_node<String> const& node, system::error_code& ec)
|
||||||
apply(
|
|
||||||
double& d,
|
|
||||||
resp3::basic_node<String> const& node,
|
|
||||||
system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
#ifdef _LIBCPP_VERSION
|
#ifdef _LIBCPP_VERSION
|
||||||
// The string in node.value is not null terminated and we also
|
// The string in node.value is not null terminated and we also
|
||||||
@@ -110,8 +97,7 @@ struct converter<double, false> {
|
|||||||
template <class CharT, class Traits, class Allocator>
|
template <class CharT, class Traits, class Allocator>
|
||||||
struct converter<std::basic_string<CharT, Traits, Allocator>, false> {
|
struct converter<std::basic_string<CharT, Traits, Allocator>, false> {
|
||||||
template <class String>
|
template <class String>
|
||||||
static void
|
static void apply(
|
||||||
apply(
|
|
||||||
std::basic_string<CharT, Traits, Allocator>& s,
|
std::basic_string<CharT, Traits, Allocator>& s,
|
||||||
resp3::basic_node<String> const& node,
|
resp3::basic_node<String> const& node,
|
||||||
system::error_code&)
|
system::error_code&)
|
||||||
@@ -123,11 +109,7 @@ struct converter<std::basic_string<CharT, Traits, Allocator>, false> {
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct from_bulk_impl {
|
struct from_bulk_impl {
|
||||||
template <class String>
|
template <class String>
|
||||||
static void
|
static void apply(T& t, resp3::basic_node<String> const& node, system::error_code& ec)
|
||||||
apply(
|
|
||||||
T& t,
|
|
||||||
resp3::basic_node<String> const& node,
|
|
||||||
system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
converter<T>::apply(t, node, ec);
|
converter<T>::apply(t, node, ec);
|
||||||
}
|
}
|
||||||
@@ -136,8 +118,7 @@ struct from_bulk_impl {
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct from_bulk_impl<std::optional<T>> {
|
struct from_bulk_impl<std::optional<T>> {
|
||||||
template <class String>
|
template <class String>
|
||||||
static void
|
static void apply(
|
||||||
apply(
|
|
||||||
std::optional<T>& op,
|
std::optional<T>& op,
|
||||||
resp3::basic_node<String> const& node,
|
resp3::basic_node<String> const& node,
|
||||||
system::error_code& ec)
|
system::error_code& ec)
|
||||||
@@ -150,11 +131,7 @@ struct from_bulk_impl<std::optional<T>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class String>
|
template <class T, class String>
|
||||||
void
|
void boost_redis_from_bulk(T& t, resp3::basic_node<String> const& node, system::error_code& ec)
|
||||||
boost_redis_from_bulk(
|
|
||||||
T& t,
|
|
||||||
resp3::basic_node<String> const& node,
|
|
||||||
system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
from_bulk_impl<T>::apply(t, node, ec);
|
from_bulk_impl<T>::apply(t, node, ec);
|
||||||
}
|
}
|
||||||
@@ -167,7 +144,9 @@ private:
|
|||||||
Result* result_;
|
Result* result_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit general_aggregate(Result* c = nullptr): result_(c) {}
|
explicit general_aggregate(Result* c = nullptr)
|
||||||
|
: result_(c)
|
||||||
|
{ }
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(resp3::basic_node<String> const& nd, system::error_code&)
|
void operator()(resp3::basic_node<String> const& nd, system::error_code&)
|
||||||
{
|
{
|
||||||
@@ -175,10 +154,18 @@ public:
|
|||||||
switch (nd.data_type) {
|
switch (nd.data_type) {
|
||||||
case resp3::type::blob_error:
|
case resp3::type::blob_error:
|
||||||
case resp3::type::simple_error:
|
case resp3::type::simple_error:
|
||||||
*result_ = error{nd.data_type, std::string{std::cbegin(nd.value), std::cend(nd.value)}};
|
*result_ = error{
|
||||||
|
nd.data_type,
|
||||||
|
std::string{std::cbegin(nd.value), std::cend(nd.value)}
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result_->value().push_back({nd.data_type, nd.aggregate_size, nd.depth, std::string{std::cbegin(nd.value), std::cend(nd.value)}});
|
result_->value().push_back({
|
||||||
|
nd.data_type,
|
||||||
|
nd.aggregate_size,
|
||||||
|
nd.depth,
|
||||||
|
std::string{std::cbegin(nd.value), std::cend(nd.value)}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -189,7 +176,9 @@ private:
|
|||||||
Node* result_;
|
Node* result_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit general_simple(Node* t = nullptr) : result_(t) {}
|
explicit general_simple(Node* t = nullptr)
|
||||||
|
: result_(t)
|
||||||
|
{ }
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(resp3::basic_node<String> const& nd, system::error_code&)
|
void operator()(resp3::basic_node<String> const& nd, system::error_code&)
|
||||||
@@ -198,7 +187,10 @@ public:
|
|||||||
switch (nd.data_type) {
|
switch (nd.data_type) {
|
||||||
case resp3::type::blob_error:
|
case resp3::type::blob_error:
|
||||||
case resp3::type::simple_error:
|
case resp3::type::simple_error:
|
||||||
*result_ = error{nd.data_type, std::string{std::cbegin(nd.value), std::cend(nd.value)}};
|
*result_ = error{
|
||||||
|
nd.data_type,
|
||||||
|
std::string{std::cbegin(nd.value), std::cend(nd.value)}
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result_->value().data_type = nd.data_type;
|
result_->value().data_type = nd.data_type;
|
||||||
@@ -212,7 +204,7 @@ public:
|
|||||||
template <class Result>
|
template <class Result>
|
||||||
class simple_impl {
|
class simple_impl {
|
||||||
public:
|
public:
|
||||||
void on_value_available(Result&) {}
|
void on_value_available(Result&) { }
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(Result& result, resp3::basic_node<String> const& node, system::error_code& ec)
|
void operator()(Result& result, resp3::basic_node<String> const& node, system::error_code& ec)
|
||||||
@@ -232,8 +224,7 @@ private:
|
|||||||
typename Result::iterator hint_;
|
typename Result::iterator hint_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void on_value_available(Result& result)
|
void on_value_available(Result& result) { hint_ = std::end(result); }
|
||||||
{ hint_ = std::end(result); }
|
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
@@ -264,8 +255,7 @@ private:
|
|||||||
bool on_key_ = true;
|
bool on_key_ = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void on_value_available(Result& result)
|
void on_value_available(Result& result) { current_ = std::end(result); }
|
||||||
{ current_ = std::end(result); }
|
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
@@ -300,7 +290,7 @@ public:
|
|||||||
template <class Result>
|
template <class Result>
|
||||||
class vector_impl {
|
class vector_impl {
|
||||||
public:
|
public:
|
||||||
void on_value_available(Result& ) { }
|
void on_value_available(Result&) { }
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
@@ -321,7 +311,7 @@ private:
|
|||||||
int i_ = -1;
|
int i_ = -1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void on_value_available(Result& ) { }
|
void on_value_available(Result&) { }
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
@@ -352,8 +342,7 @@ public:
|
|||||||
|
|
||||||
template <class Result>
|
template <class Result>
|
||||||
struct list_impl {
|
struct list_impl {
|
||||||
|
void on_value_available(Result&) { }
|
||||||
void on_value_available(Result& ) { }
|
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(Result& result, resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
@@ -374,43 +363,69 @@ struct list_impl {
|
|||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct impl_map { using type = simple_impl<T>; };
|
struct impl_map {
|
||||||
|
using type = simple_impl<T>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class Compare, class Allocator>
|
template <class Key, class Compare, class Allocator>
|
||||||
struct impl_map<std::set<Key, Compare, Allocator>> { using type = set_impl<std::set<Key, Compare, Allocator>>; };
|
struct impl_map<std::set<Key, Compare, Allocator>> {
|
||||||
|
using type = set_impl<std::set<Key, Compare, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class Compare, class Allocator>
|
template <class Key, class Compare, class Allocator>
|
||||||
struct impl_map<std::multiset<Key, Compare, Allocator>> { using type = set_impl<std::multiset<Key, Compare, Allocator>>; };
|
struct impl_map<std::multiset<Key, Compare, Allocator>> {
|
||||||
|
using type = set_impl<std::multiset<Key, Compare, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
struct impl_map<std::unordered_set<Key, Hash, KeyEqual, Allocator>> { using type = set_impl<std::unordered_set<Key, Hash, KeyEqual, Allocator>>; };
|
struct impl_map<std::unordered_set<Key, Hash, KeyEqual, Allocator>> {
|
||||||
|
using type = set_impl<std::unordered_set<Key, Hash, KeyEqual, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
struct impl_map<std::unordered_multiset<Key, Hash, KeyEqual, Allocator>> { using type = set_impl<std::unordered_multiset<Key, Hash, KeyEqual, Allocator>>; };
|
struct impl_map<std::unordered_multiset<Key, Hash, KeyEqual, Allocator>> {
|
||||||
|
using type = set_impl<std::unordered_multiset<Key, Hash, KeyEqual, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class T, class Compare, class Allocator>
|
template <class Key, class T, class Compare, class Allocator>
|
||||||
struct impl_map<std::map<Key, T, Compare, Allocator>> { using type = map_impl<std::map<Key, T, Compare, Allocator>>; };
|
struct impl_map<std::map<Key, T, Compare, Allocator>> {
|
||||||
|
using type = map_impl<std::map<Key, T, Compare, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class T, class Compare, class Allocator>
|
template <class Key, class T, class Compare, class Allocator>
|
||||||
struct impl_map<std::multimap<Key, T, Compare, Allocator>> { using type = map_impl<std::multimap<Key, T, Compare, Allocator>>; };
|
struct impl_map<std::multimap<Key, T, Compare, Allocator>> {
|
||||||
|
using type = map_impl<std::multimap<Key, T, Compare, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
struct impl_map<std::unordered_map<Key, Hash, KeyEqual, Allocator>> { using type = map_impl<std::unordered_map<Key, Hash, KeyEqual, Allocator>>; };
|
struct impl_map<std::unordered_map<Key, Hash, KeyEqual, Allocator>> {
|
||||||
|
using type = map_impl<std::unordered_map<Key, Hash, KeyEqual, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
struct impl_map<std::unordered_multimap<Key, Hash, KeyEqual, Allocator>> { using type = map_impl<std::unordered_multimap<Key, Hash, KeyEqual, Allocator>>; };
|
struct impl_map<std::unordered_multimap<Key, Hash, KeyEqual, Allocator>> {
|
||||||
|
using type = map_impl<std::unordered_multimap<Key, Hash, KeyEqual, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T, class Allocator>
|
template <class T, class Allocator>
|
||||||
struct impl_map<std::vector<T, Allocator>> { using type = vector_impl<std::vector<T, Allocator>>; };
|
struct impl_map<std::vector<T, Allocator>> {
|
||||||
|
using type = vector_impl<std::vector<T, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T, std::size_t N>
|
template <class T, std::size_t N>
|
||||||
struct impl_map<std::array<T, N>> { using type = array_impl<std::array<T, N>>; };
|
struct impl_map<std::array<T, N>> {
|
||||||
|
using type = array_impl<std::array<T, N>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T, class Allocator>
|
template <class T, class Allocator>
|
||||||
struct impl_map<std::list<T, Allocator>> { using type = list_impl<std::list<T, Allocator>>; };
|
struct impl_map<std::list<T, Allocator>> {
|
||||||
|
using type = list_impl<std::list<T, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T, class Allocator>
|
template <class T, class Allocator>
|
||||||
struct impl_map<std::deque<T, Allocator>> { using type = list_impl<std::deque<T, Allocator>>; };
|
struct impl_map<std::deque<T, Allocator>> {
|
||||||
|
using type = list_impl<std::deque<T, Allocator>>;
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
|
||||||
@@ -421,6 +436,7 @@ template <class T>
|
|||||||
class wrapper<result<T>> {
|
class wrapper<result<T>> {
|
||||||
public:
|
public:
|
||||||
using response_type = result<T>;
|
using response_type = result<T>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
response_type* result_;
|
response_type* result_;
|
||||||
typename impl_map<T>::type impl_;
|
typename impl_map<T>::type impl_;
|
||||||
@@ -433,15 +449,18 @@ private:
|
|||||||
case resp3::type::null:
|
case resp3::type::null:
|
||||||
case resp3::type::simple_error:
|
case resp3::type::simple_error:
|
||||||
case resp3::type::blob_error:
|
case resp3::type::blob_error:
|
||||||
*result_ = error{nd.data_type, {std::cbegin(nd.value), std::cend(nd.value)}};
|
*result_ = error{
|
||||||
|
nd.data_type,
|
||||||
|
{std::cbegin(nd.value), std::cend(nd.value)}
|
||||||
|
};
|
||||||
return true;
|
return true;
|
||||||
default:
|
default: return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit wrapper(response_type* t = nullptr) : result_(t)
|
explicit wrapper(response_type* t = nullptr)
|
||||||
|
: result_(t)
|
||||||
{
|
{
|
||||||
if (result_) {
|
if (result_) {
|
||||||
result_->value() = T{};
|
result_->value() = T{};
|
||||||
@@ -481,21 +500,22 @@ private:
|
|||||||
switch (nd.data_type) {
|
switch (nd.data_type) {
|
||||||
case resp3::type::blob_error:
|
case resp3::type::blob_error:
|
||||||
case resp3::type::simple_error:
|
case resp3::type::simple_error:
|
||||||
*result_ = error{nd.data_type, {std::cbegin(nd.value), std::cend(nd.value)}};
|
*result_ = error{
|
||||||
|
nd.data_type,
|
||||||
|
{std::cbegin(nd.value), std::cend(nd.value)}
|
||||||
|
};
|
||||||
return true;
|
return true;
|
||||||
default:
|
default: return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit wrapper(response_type* o = nullptr) : result_(o) {}
|
explicit wrapper(response_type* o = nullptr)
|
||||||
|
: result_(o)
|
||||||
|
{ }
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void
|
void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
operator()(
|
|
||||||
resp3::basic_node<String> const& nd,
|
|
||||||
system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(!!result_, "Unexpected null pointer");
|
BOOST_ASSERT_MSG(!!result_, "Unexpected null pointer");
|
||||||
|
|
||||||
@@ -517,6 +537,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::adapter::detail
|
} // namespace boost::redis::adapter::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_ADAPTER_ADAPTERS_HPP
|
#endif // BOOST_REDIS_ADAPTER_ADAPTERS_HPP
|
||||||
|
|||||||
@@ -7,19 +7,19 @@
|
|||||||
#ifndef BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
|
#ifndef BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
|
||||||
#define BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
|
#define BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <boost/redis/adapter/detail/result_traits.hpp>
|
||||||
#include <boost/redis/resp3/node.hpp>
|
#include <boost/redis/resp3/node.hpp>
|
||||||
#include <boost/redis/response.hpp>
|
#include <boost/redis/response.hpp>
|
||||||
#include <boost/redis/adapter/detail/result_traits.hpp>
|
|
||||||
#include <boost/mp11.hpp>
|
#include <boost/mp11.hpp>
|
||||||
#include <boost/system.hpp>
|
#include <boost/system.hpp>
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <tuple>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
namespace boost::redis::adapter::detail
|
namespace boost::redis::adapter::detail {
|
||||||
{
|
|
||||||
|
|
||||||
class ignore_adapter {
|
class ignore_adapter {
|
||||||
public:
|
public:
|
||||||
@@ -30,13 +30,15 @@ public:
|
|||||||
case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break;
|
case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break;
|
||||||
case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break;
|
case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break;
|
||||||
case resp3::type::null: ec = redis::error::resp3_null; break;
|
case resp3::type::null: ec = redis::error::resp3_null; break;
|
||||||
default:;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_supported_response_size() const noexcept
|
auto get_supported_response_size() const noexcept
|
||||||
{ return static_cast<std::size_t>(-1);}
|
{
|
||||||
|
return static_cast<std::size_t>(-1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Response>
|
template <class Response>
|
||||||
@@ -50,14 +52,13 @@ private:
|
|||||||
adapters_array_type adapters_;
|
adapters_array_type adapters_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit static_adapter(Response& r)
|
explicit static_adapter(Response& r) { assigner<size - 1>::assign(adapters_, r); }
|
||||||
{
|
|
||||||
assigner<size - 1>::assign(adapters_, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_supported_response_size() const noexcept
|
auto get_supported_response_size() const noexcept
|
||||||
{ return size;}
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(std::size_t i, resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(std::size_t i, resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
@@ -65,7 +66,11 @@ public:
|
|||||||
using std::visit;
|
using std::visit;
|
||||||
// I am usure whether this should be an error or an assertion.
|
// I am usure whether this should be an error or an assertion.
|
||||||
BOOST_ASSERT(i < adapters_.size());
|
BOOST_ASSERT(i < adapters_.size());
|
||||||
visit([&](auto& arg){arg(nd, ec);}, adapters_.at(i));
|
visit(
|
||||||
|
[&](auto& arg) {
|
||||||
|
arg(nd, ec);
|
||||||
|
},
|
||||||
|
adapters_.at(i));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,9 +86,10 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto
|
auto get_supported_response_size() const noexcept
|
||||||
get_supported_response_size() const noexcept
|
{
|
||||||
{ return static_cast<std::size_t>(-1);}
|
return static_cast<std::size_t>(-1);
|
||||||
|
}
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(std::size_t, resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(std::size_t, resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
@@ -100,8 +106,7 @@ struct response_traits<ignore_t> {
|
|||||||
using response_type = ignore_t;
|
using response_type = ignore_t;
|
||||||
using adapter_type = detail::ignore_adapter;
|
using adapter_type = detail::ignore_adapter;
|
||||||
|
|
||||||
static auto adapt(response_type&) noexcept
|
static auto adapt(response_type&) noexcept { return detail::ignore_adapter{}; }
|
||||||
{ return detail::ignore_adapter{}; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@@ -109,8 +114,7 @@ struct response_traits<result<ignore_t>> {
|
|||||||
using response_type = result<ignore_t>;
|
using response_type = result<ignore_t>;
|
||||||
using adapter_type = detail::ignore_adapter;
|
using adapter_type = detail::ignore_adapter;
|
||||||
|
|
||||||
static auto adapt(response_type&) noexcept
|
static auto adapt(response_type&) noexcept { return detail::ignore_adapter{}; }
|
||||||
{ return detail::ignore_adapter{}; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class String, class Allocator>
|
template <class String, class Allocator>
|
||||||
@@ -118,31 +122,35 @@ struct response_traits<result<std::vector<resp3::basic_node<String>, Allocator>>
|
|||||||
using response_type = result<std::vector<resp3::basic_node<String>, Allocator>>;
|
using response_type = result<std::vector<resp3::basic_node<String>, Allocator>>;
|
||||||
using adapter_type = vector_adapter<response_type>;
|
using adapter_type = vector_adapter<response_type>;
|
||||||
|
|
||||||
static auto adapt(response_type& v) noexcept
|
static auto adapt(response_type& v) noexcept { return adapter_type{v}; }
|
||||||
{ return adapter_type{v}; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ...Ts>
|
template <class... Ts>
|
||||||
struct response_traits<response<Ts...>> {
|
struct response_traits<response<Ts...>> {
|
||||||
using response_type = response<Ts...>;
|
using response_type = response<Ts...>;
|
||||||
using adapter_type = static_adapter<response_type>;
|
using adapter_type = static_adapter<response_type>;
|
||||||
|
|
||||||
static auto adapt(response_type& r) noexcept
|
static auto adapt(response_type& r) noexcept { return adapter_type{r}; }
|
||||||
{ return adapter_type{r}; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Adapter>
|
template <class Adapter>
|
||||||
class wrapper {
|
class wrapper {
|
||||||
public:
|
public:
|
||||||
explicit wrapper(Adapter adapter) : adapter_{adapter} {}
|
explicit wrapper(Adapter adapter)
|
||||||
|
: adapter_{adapter}
|
||||||
|
{ }
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
|
void operator()(resp3::basic_node<String> const& nd, system::error_code& ec)
|
||||||
{ return adapter_(0, nd, ec); }
|
{
|
||||||
|
return adapter_(0, nd, ec);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_supported_response_size() const noexcept
|
auto get_supported_response_size() const noexcept
|
||||||
{ return adapter_.get_supported_response_size();}
|
{
|
||||||
|
return adapter_.get_supported_response_size();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Adapter adapter_;
|
Adapter adapter_;
|
||||||
@@ -154,6 +162,6 @@ auto make_adapter_wrapper(Adapter adapter)
|
|||||||
return wrapper{adapter};
|
return wrapper{adapter};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::adapter::detail
|
} // namespace boost::redis::adapter::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
|
#endif // BOOST_REDIS_ADAPTER_DETAIL_RESPONSE_TRAITS_HPP
|
||||||
|
|||||||
@@ -7,21 +7,21 @@
|
|||||||
#ifndef BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
|
#ifndef BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
|
||||||
#define BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
|
#define BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
|
||||||
|
|
||||||
#include <boost/redis/error.hpp>
|
|
||||||
#include <boost/redis/resp3/type.hpp>
|
|
||||||
#include <boost/redis/ignore.hpp>
|
|
||||||
#include <boost/redis/adapter/detail/adapters.hpp>
|
#include <boost/redis/adapter/detail/adapters.hpp>
|
||||||
#include <boost/redis/adapter/result.hpp>
|
|
||||||
#include <boost/redis/adapter/ignore.hpp>
|
#include <boost/redis/adapter/ignore.hpp>
|
||||||
|
#include <boost/redis/adapter/result.hpp>
|
||||||
|
#include <boost/redis/error.hpp>
|
||||||
|
#include <boost/redis/ignore.hpp>
|
||||||
|
#include <boost/redis/resp3/type.hpp>
|
||||||
|
|
||||||
#include <boost/mp11.hpp>
|
#include <boost/mp11.hpp>
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <tuple>
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <tuple>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace boost::redis::adapter::detail
|
namespace boost::redis::adapter::detail {
|
||||||
{
|
|
||||||
|
|
||||||
/* Traits class for response objects.
|
/* Traits class for response objects.
|
||||||
*
|
*
|
||||||
@@ -65,9 +65,11 @@ struct result_traits<result<std::vector<resp3::basic_node<String>, Allocator>>>
|
|||||||
template <class T>
|
template <class T>
|
||||||
using adapter_t = typename result_traits<std::decay_t<T>>::adapter_type;
|
using adapter_t = typename result_traits<std::decay_t<T>>::adapter_type;
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
auto internal_adapt(T& t) noexcept
|
auto internal_adapt(T& t) noexcept
|
||||||
{ return result_traits<std::decay_t<T>>::adapt(t); }
|
{
|
||||||
|
return result_traits<std::decay_t<T>>::adapt(t);
|
||||||
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
struct assigner {
|
struct assigner {
|
||||||
@@ -94,12 +96,8 @@ class static_aggregate_adapter;
|
|||||||
template <class Tuple>
|
template <class Tuple>
|
||||||
class static_aggregate_adapter<result<Tuple>> {
|
class static_aggregate_adapter<result<Tuple>> {
|
||||||
private:
|
private:
|
||||||
using adapters_array_type =
|
using adapters_array_type = std::array<
|
||||||
std::array<
|
mp11::mp_rename<mp11::mp_transform<adapter_t, Tuple>, std::variant>,
|
||||||
mp11::mp_rename<
|
|
||||||
mp11::mp_transform<
|
|
||||||
adapter_t, Tuple>,
|
|
||||||
std::variant>,
|
|
||||||
std::tuple_size<Tuple>::value>;
|
std::tuple_size<Tuple>::value>;
|
||||||
|
|
||||||
// Tuple element we are currently on.
|
// Tuple element we are currently on.
|
||||||
@@ -148,19 +146,22 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
visit([&](auto& arg){arg(elem, ec);}, adapters_[i_]);
|
visit(
|
||||||
|
[&](auto& arg) {
|
||||||
|
arg(elem, ec);
|
||||||
|
},
|
||||||
|
adapters_[i_]);
|
||||||
count(elem);
|
count(elem);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class... Ts>
|
template <class... Ts>
|
||||||
struct result_traits<result<std::tuple<Ts...>>>
|
struct result_traits<result<std::tuple<Ts...>>> {
|
||||||
{
|
|
||||||
using response_type = result<std::tuple<Ts...>>;
|
using response_type = result<std::tuple<Ts...>>;
|
||||||
using adapter_type = static_aggregate_adapter<response_type>;
|
using adapter_type = static_aggregate_adapter<response_type>;
|
||||||
static auto adapt(response_type& r) noexcept { return adapter_type{&r}; }
|
static auto adapt(response_type& r) noexcept { return adapter_type{&r}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::adapter::detail
|
} // namespace boost::redis::adapter::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
|
#endif // BOOST_REDIS_ADAPTER_RESPONSE_TRAITS_HPP
|
||||||
|
|||||||
@@ -7,13 +7,14 @@
|
|||||||
#ifndef BOOST_REDIS_ADAPTER_IGNORE_HPP
|
#ifndef BOOST_REDIS_ADAPTER_IGNORE_HPP
|
||||||
#define BOOST_REDIS_ADAPTER_IGNORE_HPP
|
#define BOOST_REDIS_ADAPTER_IGNORE_HPP
|
||||||
|
|
||||||
#include <boost/redis/resp3/node.hpp>
|
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
|
#include <boost/redis/resp3/node.hpp>
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace boost::redis::adapter
|
namespace boost::redis::adapter {
|
||||||
{
|
|
||||||
|
|
||||||
/** @brief An adapter that ignores responses
|
/** @brief An adapter that ignores responses
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -27,11 +28,11 @@ struct ignore {
|
|||||||
case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break;
|
case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break;
|
||||||
case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break;
|
case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break;
|
||||||
case resp3::type::null: ec = redis::error::resp3_null; break;
|
case resp3::type::null: ec = redis::error::resp3_null; break;
|
||||||
default:;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::adapter
|
} // namespace boost::redis::adapter
|
||||||
|
|
||||||
#endif // BOOST_REDIS_ADAPTER_IGNORE_HPP
|
#endif // BOOST_REDIS_ADAPTER_IGNORE_HPP
|
||||||
|
|||||||
@@ -8,13 +8,14 @@
|
|||||||
#ifndef BOOST_REDIS_ADAPTER_RESULT_HPP
|
#ifndef BOOST_REDIS_ADAPTER_RESULT_HPP
|
||||||
#define BOOST_REDIS_ADAPTER_RESULT_HPP
|
#define BOOST_REDIS_ADAPTER_RESULT_HPP
|
||||||
|
|
||||||
#include <boost/redis/resp3/type.hpp>
|
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
|
#include <boost/redis/resp3/type.hpp>
|
||||||
|
|
||||||
#include <boost/system/result.hpp>
|
#include <boost/system/result.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace boost::redis::adapter
|
namespace boost::redis::adapter {
|
||||||
{
|
|
||||||
|
|
||||||
/** @brief Stores any resp3 error
|
/** @brief Stores any resp3 error
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -44,10 +45,7 @@ inline bool operator==(error const& a, error const& b)
|
|||||||
* @param a Left hand side error object.
|
* @param a Left hand side error object.
|
||||||
* @param b Right hand side error object.
|
* @param b Right hand side error object.
|
||||||
*/
|
*/
|
||||||
inline bool operator!=(error const& a, error const& b)
|
inline bool operator!=(error const& a, error const& b) { return !(a == b); }
|
||||||
{
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @brief Stores response to individual Redis commands
|
/** @brief Stores response to individual Redis commands
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -55,27 +53,19 @@ inline bool operator!=(error const& a, error const& b)
|
|||||||
template <class Value>
|
template <class Value>
|
||||||
using result = system::result<Value, error>;
|
using result = system::result<Value, error>;
|
||||||
|
|
||||||
BOOST_NORETURN inline void
|
BOOST_NORETURN inline void throw_exception_from_error(error const& e, boost::source_location const&)
|
||||||
throw_exception_from_error(error const & e, boost::source_location const &)
|
|
||||||
{
|
{
|
||||||
system::error_code ec;
|
system::error_code ec;
|
||||||
switch (e.data_type) {
|
switch (e.data_type) {
|
||||||
case resp3::type::simple_error:
|
case resp3::type::simple_error: ec = redis::error::resp3_simple_error; break;
|
||||||
ec = redis::error::resp3_simple_error;
|
case resp3::type::blob_error: ec = redis::error::resp3_blob_error; break;
|
||||||
break;
|
case resp3::type::null: ec = redis::error::resp3_null; break;
|
||||||
case resp3::type::blob_error:
|
default: BOOST_ASSERT_MSG(false, "Unexpected data type.");
|
||||||
ec = redis::error::resp3_blob_error;
|
|
||||||
break;
|
|
||||||
case resp3::type::null:
|
|
||||||
ec = redis::error::resp3_null;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BOOST_ASSERT_MSG(false, "Unexpected data type.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw system::system_error(ec, e.diagnostic);
|
throw system::system_error(ec, e.diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::adapter
|
} // namespace boost::redis::adapter
|
||||||
|
|
||||||
#endif // BOOST_REDIS_ADAPTER_RESULT_HPP
|
#endif // BOOST_REDIS_ADAPTER_RESULT_HPP
|
||||||
|
|||||||
@@ -7,13 +7,12 @@
|
|||||||
#ifndef BOOST_REDIS_CONFIG_HPP
|
#ifndef BOOST_REDIS_CONFIG_HPP
|
||||||
#define BOOST_REDIS_CONFIG_HPP
|
#define BOOST_REDIS_CONFIG_HPP
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <optional>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
/** @brief Address of a Redis server
|
/** @brief Address of a Redis server
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -88,6 +87,6 @@ struct config {
|
|||||||
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)();
|
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_CONFIG_HPP
|
#endif // BOOST_REDIS_CONFIG_HPP
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
#include <boost/asio/steady_timer.hpp>
|
#include <boost/asio/steady_timer.hpp>
|
||||||
#include <boost/asio/write.hpp>
|
#include <boost/asio/write.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <boost/core/ignore_unused.hpp>
|
#include <boost/core/ignore_unused.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
@@ -53,8 +52,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace boost::redis {
|
namespace boost::redis {
|
||||||
namespace detail
|
namespace detail {
|
||||||
{
|
|
||||||
|
|
||||||
template <class AsyncReadStream, class DynamicBuffer>
|
template <class AsyncReadStream, class DynamicBuffer>
|
||||||
class append_some_op {
|
class append_some_op {
|
||||||
@@ -67,17 +65,15 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
append_some_op(AsyncReadStream& stream, DynamicBuffer buf, std::size_t size)
|
append_some_op(AsyncReadStream& stream, DynamicBuffer buf, std::size_t size)
|
||||||
: stream_ {stream}
|
: stream_{stream}
|
||||||
, buf_ {std::move(buf)}
|
, buf_{std::move(buf)}
|
||||||
, size_{size}
|
, size_{size}
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()( Self& self
|
void operator()(Self& self, system::error_code ec = {}, std::size_t n = 0)
|
||||||
, system::error_code ec = {}
|
|
||||||
, std::size_t n = 0)
|
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_)
|
BOOST_ASIO_CORO_REENTER(coro_)
|
||||||
{
|
{
|
||||||
tmp_ = buf_.size();
|
tmp_ = buf_.size();
|
||||||
buf_.grow(size_);
|
buf_.grow(size_);
|
||||||
@@ -96,22 +92,22 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class AsyncReadStream, class DynamicBuffer, class CompletionToken>
|
template <class AsyncReadStream, class DynamicBuffer, class CompletionToken>
|
||||||
auto
|
auto async_append_some(
|
||||||
async_append_some(
|
|
||||||
AsyncReadStream& stream,
|
AsyncReadStream& stream,
|
||||||
DynamicBuffer buffer,
|
DynamicBuffer buffer,
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
CompletionToken&& token)
|
CompletionToken&& token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code, std::size_t)>(
|
||||||
< CompletionToken
|
append_some_op<AsyncReadStream, DynamicBuffer>{stream, buffer, size},
|
||||||
, void(system::error_code, std::size_t)
|
token,
|
||||||
>(append_some_op<AsyncReadStream, DynamicBuffer> {stream, buffer, size}, token, stream);
|
stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Executor>
|
template <class Executor>
|
||||||
using exec_notifier_type =
|
using exec_notifier_type = asio::experimental::channel<
|
||||||
asio::experimental::channel<Executor, void(system::error_code, std::size_t)>;
|
Executor,
|
||||||
|
void(system::error_code, std::size_t)>;
|
||||||
|
|
||||||
template <class Conn>
|
template <class Conn>
|
||||||
struct exec_op {
|
struct exec_op {
|
||||||
@@ -124,9 +120,9 @@ struct exec_op {
|
|||||||
asio::coroutine coro_{};
|
asio::coroutine coro_{};
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()(Self& self , system::error_code = {}, std::size_t = 0)
|
void operator()(Self& self, system::error_code = {}, std::size_t = 0)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_)
|
BOOST_ASIO_CORO_REENTER(coro_)
|
||||||
{
|
{
|
||||||
// Check whether the user wants to wait for the connection to
|
// Check whether the user wants to wait for the connection to
|
||||||
// be stablished.
|
// be stablished.
|
||||||
@@ -188,13 +184,11 @@ struct writer_op {
|
|||||||
asio::coroutine coro{};
|
asio::coroutine coro{};
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()( Self& self
|
void operator()(Self& self, system::error_code ec = {}, std::size_t n = 0)
|
||||||
, system::error_code ec = {}
|
|
||||||
, std::size_t n = 0)
|
|
||||||
{
|
{
|
||||||
ignore_unused(n);
|
ignore_unused(n);
|
||||||
|
|
||||||
BOOST_ASIO_CORO_REENTER (coro) for (;;)
|
BOOST_ASIO_CORO_REENTER(coro) for (;;)
|
||||||
{
|
{
|
||||||
while (conn_->mpx_.prepare_write() != 0) {
|
while (conn_->mpx_.prepare_write() != 0) {
|
||||||
if (conn_->use_ssl()) {
|
if (conn_->use_ssl()) {
|
||||||
@@ -248,7 +242,10 @@ struct writer_op {
|
|||||||
|
|
||||||
template <class Conn, class Logger>
|
template <class Conn, class Logger>
|
||||||
struct reader_op {
|
struct reader_op {
|
||||||
using dyn_buffer_type = asio::dynamic_string_buffer<char, std::char_traits<char>, std::allocator<char>>;
|
using dyn_buffer_type = asio::dynamic_string_buffer<
|
||||||
|
char,
|
||||||
|
std::char_traits<char>,
|
||||||
|
std::allocator<char>>;
|
||||||
|
|
||||||
// TODO: Move this to config so the user can fine tune?
|
// TODO: Move this to config so the user can fine tune?
|
||||||
static constexpr std::size_t buffer_growth_hint = 4096;
|
static constexpr std::size_t buffer_growth_hint = 4096;
|
||||||
@@ -259,13 +256,11 @@ struct reader_op {
|
|||||||
asio::coroutine coro{};
|
asio::coroutine coro{};
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()( Self& self
|
void operator()(Self& self, system::error_code ec = {}, std::size_t n = 0)
|
||||||
, system::error_code ec = {}
|
|
||||||
, std::size_t n = 0)
|
|
||||||
{
|
{
|
||||||
ignore_unused(n);
|
ignore_unused(n);
|
||||||
|
|
||||||
BOOST_ASIO_CORO_REENTER (coro) for (;;)
|
BOOST_ASIO_CORO_REENTER(coro) for (;;)
|
||||||
{
|
{
|
||||||
// Appends some data to the buffer if necessary.
|
// Appends some data to the buffer if necessary.
|
||||||
if (!res_.first.has_value() || conn_->mpx_.is_data_needed()) {
|
if (!res_.first.has_value() || conn_->mpx_.is_data_needed()) {
|
||||||
@@ -331,7 +326,6 @@ struct reader_op {
|
|||||||
self.complete(asio::error::operation_aborted);
|
self.complete(asio::error::operation_aborted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,21 +344,22 @@ public:
|
|||||||
run_op(Conn* conn, Logger l)
|
run_op(Conn* conn, Logger l)
|
||||||
: conn_{conn}
|
: conn_{conn}
|
||||||
, logger_{l}
|
, logger_{l}
|
||||||
{}
|
{ }
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()( Self& self
|
void operator()(
|
||||||
, order_t order = {}
|
Self& self,
|
||||||
, system::error_code ec0 = {}
|
order_t order = {},
|
||||||
, system::error_code ec1 = {}
|
system::error_code ec0 = {},
|
||||||
, system::error_code ec2 = {}
|
system::error_code ec1 = {},
|
||||||
, system::error_code ec3 = {}
|
system::error_code ec2 = {},
|
||||||
, system::error_code ec4 = {})
|
system::error_code ec3 = {},
|
||||||
|
system::error_code ec4 = {})
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_) for (;;)
|
BOOST_ASIO_CORO_REENTER(coro_) for (;;)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
conn_->resv_.async_resolve(asio::prepend(std::move(self), order_t {}));
|
conn_->resv_.async_resolve(asio::prepend(std::move(self), order_t{}));
|
||||||
|
|
||||||
logger_.on_resolve(ec0, conn_->resv_.results());
|
logger_.on_resolve(ec0, conn_->resv_.results());
|
||||||
|
|
||||||
@@ -377,7 +372,7 @@ public:
|
|||||||
conn_->ctor_.async_connect(
|
conn_->ctor_.async_connect(
|
||||||
conn_->next_layer().next_layer(),
|
conn_->next_layer().next_layer(),
|
||||||
conn_->resv_.results(),
|
conn_->resv_.results(),
|
||||||
asio::prepend(std::move(self), order_t {}));
|
asio::prepend(std::move(self), order_t{}));
|
||||||
|
|
||||||
logger_.on_connect(ec0, conn_->ctor_.endpoint());
|
logger_.on_connect(ec0, conn_->ctor_.endpoint());
|
||||||
|
|
||||||
@@ -391,13 +386,8 @@ public:
|
|||||||
conn_->next_layer().async_handshake(
|
conn_->next_layer().async_handshake(
|
||||||
asio::ssl::stream_base::client,
|
asio::ssl::stream_base::client,
|
||||||
asio::prepend(
|
asio::prepend(
|
||||||
asio::cancel_after(
|
asio::cancel_after(conn_->cfg_.ssl_handshake_timeout, std::move(self)),
|
||||||
conn_->cfg_.ssl_handshake_timeout,
|
order_t{}));
|
||||||
std::move(self)
|
|
||||||
),
|
|
||||||
order_t {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
logger_.on_ssl_handshake(ec0);
|
logger_.on_ssl_handshake(ec0);
|
||||||
|
|
||||||
@@ -414,14 +404,22 @@ public:
|
|||||||
// causing an authentication problem.
|
// causing an authentication problem.
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
asio::experimental::make_parallel_group(
|
asio::experimental::make_parallel_group(
|
||||||
[this](auto token) { return conn_->handshaker_.async_hello(*conn_, logger_, token); },
|
[this](auto token) {
|
||||||
[this](auto token) { return conn_->health_checker_.async_ping(*conn_, logger_, token); },
|
return conn_->handshaker_.async_hello(*conn_, logger_, token);
|
||||||
[this](auto token) { return conn_->health_checker_.async_check_timeout(*conn_, logger_, token);},
|
},
|
||||||
[this](auto token) { return conn_->reader(logger_, token);},
|
[this](auto token) {
|
||||||
[this](auto token) { return conn_->writer(logger_, token);}
|
return conn_->health_checker_.async_ping(*conn_, logger_, token);
|
||||||
).async_wait(
|
},
|
||||||
asio::experimental::wait_for_one_error(),
|
[this](auto token) {
|
||||||
std::move(self));
|
return conn_->health_checker_.async_check_timeout(*conn_, logger_, token);
|
||||||
|
},
|
||||||
|
[this](auto token) {
|
||||||
|
return conn_->reader(logger_, token);
|
||||||
|
},
|
||||||
|
[this](auto token) {
|
||||||
|
return conn_->writer(logger_, token);
|
||||||
|
})
|
||||||
|
.async_wait(asio::experimental::wait_for_one_error(), std::move(self));
|
||||||
|
|
||||||
if (order[0] == 0 && !!ec0) {
|
if (order[0] == 0 && !!ec0) {
|
||||||
self.complete(ec0);
|
self.complete(ec0);
|
||||||
@@ -449,7 +447,7 @@ public:
|
|||||||
conn_->writer_timer_.expires_after(conn_->cfg_.reconnect_wait_interval);
|
conn_->writer_timer_.expires_after(conn_->cfg_.reconnect_wait_interval);
|
||||||
|
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
conn_->writer_timer_.async_wait(asio::prepend(std::move(self), order_t {}));
|
conn_->writer_timer_.async_wait(asio::prepend(std::move(self), order_t{}));
|
||||||
if (ec0) {
|
if (ec0) {
|
||||||
self.complete(ec0);
|
self.complete(ec0);
|
||||||
return;
|
return;
|
||||||
@@ -465,7 +463,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace detail
|
||||||
|
|
||||||
/** @brief A SSL connection to the Redis server.
|
/** @brief A SSL connection to the Redis server.
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -489,13 +487,11 @@ public:
|
|||||||
using executor_type = Executor;
|
using executor_type = Executor;
|
||||||
|
|
||||||
/// Returns the associated executor.
|
/// Returns the associated executor.
|
||||||
executor_type get_executor() noexcept
|
executor_type get_executor() noexcept { return writer_timer_.get_executor(); }
|
||||||
{return writer_timer_.get_executor();}
|
|
||||||
|
|
||||||
/// Rebinds the socket type to another executor.
|
/// Rebinds the socket type to another executor.
|
||||||
template <class Executor1>
|
template <class Executor1>
|
||||||
struct rebind_executor
|
struct rebind_executor {
|
||||||
{
|
|
||||||
/// The connection type when rebound to the specified executor.
|
/// The connection type when rebound to the specified executor.
|
||||||
using other = basic_connection<Executor1>;
|
using other = basic_connection<Executor1>;
|
||||||
};
|
};
|
||||||
@@ -505,8 +501,7 @@ public:
|
|||||||
* @param ex Executor on which connection operation will run.
|
* @param ex Executor on which connection operation will run.
|
||||||
* @param ctx SSL context.
|
* @param ctx SSL context.
|
||||||
*/
|
*/
|
||||||
explicit
|
explicit basic_connection(
|
||||||
basic_connection(
|
|
||||||
executor_type ex,
|
executor_type ex,
|
||||||
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client})
|
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client})
|
||||||
: ctx_{std::move(ctx)}
|
: ctx_{std::move(ctx)}
|
||||||
@@ -521,8 +516,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs from a context.
|
/// Constructs from a context.
|
||||||
explicit
|
explicit basic_connection(
|
||||||
basic_connection(
|
|
||||||
asio::io_context& ioc,
|
asio::io_context& ioc,
|
||||||
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client})
|
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client})
|
||||||
: basic_connection(ioc.get_executor(), std::move(ctx))
|
: basic_connection(ioc.get_executor(), std::move(ctx))
|
||||||
@@ -568,11 +562,7 @@ public:
|
|||||||
template <
|
template <
|
||||||
class Logger = logger,
|
class Logger = logger,
|
||||||
class CompletionToken = asio::default_completion_token_t<executor_type>>
|
class CompletionToken = asio::default_completion_token_t<executor_type>>
|
||||||
auto
|
auto async_run(config const& cfg = {}, Logger l = Logger{}, CompletionToken&& token = {})
|
||||||
async_run(
|
|
||||||
config const& cfg = {},
|
|
||||||
Logger l = Logger{},
|
|
||||||
CompletionToken&& token = {})
|
|
||||||
{
|
{
|
||||||
cfg_ = cfg;
|
cfg_ = cfg;
|
||||||
resv_.set_config(cfg);
|
resv_.set_config(cfg);
|
||||||
@@ -581,10 +571,10 @@ public:
|
|||||||
handshaker_.set_config(cfg);
|
handshaker_.set_config(cfg);
|
||||||
l.set_prefix(cfg.log_prefix);
|
l.set_prefix(cfg.log_prefix);
|
||||||
|
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
detail::run_op<this_type, Logger>{this, l},
|
||||||
, void(system::error_code)
|
token,
|
||||||
>(detail::run_op<this_type, Logger>{this, l}, token, writer_timer_);
|
writer_timer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Receives server side pushes asynchronously.
|
/** @brief Receives server side pushes asynchronously.
|
||||||
@@ -611,7 +601,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
template <class CompletionToken = asio::default_completion_token_t<executor_type>>
|
template <class CompletionToken = asio::default_completion_token_t<executor_type>>
|
||||||
auto async_receive(CompletionToken&& token = {})
|
auto async_receive(CompletionToken&& token = {})
|
||||||
{ return receive_channel_.async_receive(std::forward<CompletionToken>(token)); }
|
{
|
||||||
|
return receive_channel_.async_receive(std::forward<CompletionToken>(token));
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief Receives server pushes synchronously without blocking.
|
/** @brief Receives server pushes synchronously without blocking.
|
||||||
*
|
*
|
||||||
@@ -628,8 +620,7 @@ public:
|
|||||||
{
|
{
|
||||||
std::size_t size = 0;
|
std::size_t size = 0;
|
||||||
|
|
||||||
auto f = [&](system::error_code const& ec2, std::size_t n)
|
auto f = [&](system::error_code const& ec2, std::size_t n) {
|
||||||
{
|
|
||||||
ec = ec2;
|
ec = ec2;
|
||||||
size = n;
|
size = n;
|
||||||
};
|
};
|
||||||
@@ -669,13 +660,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
template <
|
template <
|
||||||
class Response = ignore_t,
|
class Response = ignore_t,
|
||||||
class CompletionToken = asio::default_completion_token_t<executor_type>
|
class CompletionToken = asio::default_completion_token_t<executor_type>>
|
||||||
>
|
auto async_exec(request const& req, Response& resp = ignore, CompletionToken&& token = {})
|
||||||
auto
|
|
||||||
async_exec(
|
|
||||||
request const& req,
|
|
||||||
Response& resp = ignore,
|
|
||||||
CompletionToken&& token = {})
|
|
||||||
{
|
{
|
||||||
return this->async_exec(req, any_adapter(resp), std::forward<CompletionToken>(token));
|
return this->async_exec(req, any_adapter(resp), std::forward<CompletionToken>(token));
|
||||||
}
|
}
|
||||||
@@ -686,26 +672,26 @@ public:
|
|||||||
* encapsulates a reference to a response object.
|
* encapsulates a reference to a response object.
|
||||||
*/
|
*/
|
||||||
template <class CompletionToken = asio::default_completion_token_t<executor_type>>
|
template <class CompletionToken = asio::default_completion_token_t<executor_type>>
|
||||||
auto
|
auto async_exec(request const& req, any_adapter adapter, CompletionToken&& token = {})
|
||||||
async_exec(
|
|
||||||
request const& req,
|
|
||||||
any_adapter adapter,
|
|
||||||
CompletionToken&& token = {})
|
|
||||||
{
|
{
|
||||||
auto& adapter_impl = adapter.impl_;
|
auto& adapter_impl = adapter.impl_;
|
||||||
BOOST_ASSERT_MSG(req.get_expected_responses() <= adapter_impl.supported_response_size, "Request and response have incompatible sizes.");
|
BOOST_ASSERT_MSG(
|
||||||
|
req.get_expected_responses() <= adapter_impl.supported_response_size,
|
||||||
|
"Request and response have incompatible sizes.");
|
||||||
|
|
||||||
auto notifier = std::make_shared<detail::exec_notifier_type<executor_type>>(get_executor(), 1);
|
auto notifier = std::make_shared<detail::exec_notifier_type<executor_type>>(
|
||||||
|
get_executor(),
|
||||||
|
1);
|
||||||
auto info = detail::make_elem(req, std::move(adapter_impl.adapt_fn));
|
auto info = detail::make_elem(req, std::move(adapter_impl.adapt_fn));
|
||||||
|
|
||||||
info->set_done_callback([notifier]() {
|
info->set_done_callback([notifier]() {
|
||||||
notifier->try_send(std::error_code{}, 0);
|
notifier->try_send(std::error_code{}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code, std::size_t)>(
|
||||||
< CompletionToken
|
detail::exec_op<this_type>{this, notifier, info},
|
||||||
, void(system::error_code, std::size_t)
|
token,
|
||||||
>(detail::exec_op<this_type>{this, notifier, info}, token, writer_timer_);
|
writer_timer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Cancel operations.
|
/** @brief Cancel operations.
|
||||||
@@ -722,24 +708,14 @@ public:
|
|||||||
void cancel(operation op = operation::all)
|
void cancel(operation op = operation::all)
|
||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case operation::resolve:
|
case operation::resolve: resv_.cancel(); break;
|
||||||
resv_.cancel();
|
case operation::exec: mpx_.cancel_waiting(); break;
|
||||||
break;
|
|
||||||
case operation::exec:
|
|
||||||
mpx_.cancel_waiting();
|
|
||||||
break;
|
|
||||||
case operation::reconnection:
|
case operation::reconnection:
|
||||||
cfg_.reconnect_wait_interval = std::chrono::seconds::zero();
|
cfg_.reconnect_wait_interval = std::chrono::seconds::zero();
|
||||||
break;
|
break;
|
||||||
case operation::run:
|
case operation::run: cancel_run(); break;
|
||||||
cancel_run();
|
case operation::receive: receive_channel_.cancel(); break;
|
||||||
break;
|
case operation::health_check: health_checker_.cancel(); break;
|
||||||
case operation::receive:
|
|
||||||
receive_channel_.cancel();
|
|
||||||
break;
|
|
||||||
case operation::health_check:
|
|
||||||
health_checker_.cancel();
|
|
||||||
break;
|
|
||||||
case operation::all:
|
case operation::all:
|
||||||
resv_.cancel();
|
resv_.cancel();
|
||||||
cfg_.reconnect_wait_interval = std::chrono::seconds::zero();
|
cfg_.reconnect_wait_interval = std::chrono::seconds::zero();
|
||||||
@@ -752,50 +728,52 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto run_is_canceled() const noexcept
|
auto run_is_canceled() const noexcept { return mpx_.get_cancel_run_state(); }
|
||||||
{ return mpx_.get_cancel_run_state(); }
|
|
||||||
|
|
||||||
/// Returns true if the connection was canceled.
|
/// Returns true if the connection was canceled.
|
||||||
bool will_reconnect() const noexcept
|
bool will_reconnect() const noexcept
|
||||||
{ return cfg_.reconnect_wait_interval != std::chrono::seconds::zero();}
|
{
|
||||||
|
return cfg_.reconnect_wait_interval != std::chrono::seconds::zero();
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the ssl context.
|
/// Returns the ssl context.
|
||||||
auto const& get_ssl_context() const noexcept
|
auto const& get_ssl_context() const noexcept { return ctx_; }
|
||||||
{ return ctx_;}
|
|
||||||
|
|
||||||
/// Resets the underlying stream.
|
/// Resets the underlying stream.
|
||||||
void reset_stream()
|
void reset_stream()
|
||||||
{ stream_ = std::make_unique<next_layer_type>(writer_timer_.get_executor(), ctx_); }
|
{
|
||||||
|
stream_ = std::make_unique<next_layer_type>(writer_timer_.get_executor(), ctx_);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a reference to the next layer.
|
/// Returns a reference to the next layer.
|
||||||
auto& next_layer() noexcept
|
auto& next_layer() noexcept { return *stream_; }
|
||||||
{ return *stream_; }
|
|
||||||
|
|
||||||
/// Returns a const reference to the next layer.
|
/// Returns a const reference to the next layer.
|
||||||
auto const& next_layer() const noexcept
|
auto const& next_layer() const noexcept { return *stream_; }
|
||||||
{ return *stream_; }
|
|
||||||
|
|
||||||
/// Sets the response object of `async_receive` operations.
|
/// Sets the response object of `async_receive` operations.
|
||||||
template <class Response>
|
template <class Response>
|
||||||
void set_receive_response(Response& response)
|
void set_receive_response(Response& response)
|
||||||
{ mpx_.set_receive_response(response); }
|
{
|
||||||
|
mpx_.set_receive_response(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns connection usage information.
|
/// Returns connection usage information.
|
||||||
usage get_usage() const noexcept
|
usage get_usage() const noexcept { return mpx_.get_usage(); }
|
||||||
{ return mpx_.get_usage(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using clock_type = std::chrono::steady_clock;
|
using clock_type = std::chrono::steady_clock;
|
||||||
using clock_traits_type = asio::wait_traits<clock_type>;
|
using clock_traits_type = asio::wait_traits<clock_type>;
|
||||||
using timer_type = asio::basic_waitable_timer<clock_type, clock_traits_type, executor_type>;
|
using timer_type = asio::basic_waitable_timer<clock_type, clock_traits_type, executor_type>;
|
||||||
|
|
||||||
using receive_channel_type = asio::experimental::channel<executor_type, void(system::error_code, std::size_t)>;
|
using receive_channel_type = asio::experimental::channel<
|
||||||
|
executor_type,
|
||||||
|
void(system::error_code, std::size_t)>;
|
||||||
using resolver_type = detail::resolver<Executor>;
|
using resolver_type = detail::resolver<Executor>;
|
||||||
using health_checker_type = detail::health_checker<Executor>;
|
using health_checker_type = detail::health_checker<Executor>;
|
||||||
using resp3_handshaker_type = detail::resp3_handshaker<executor_type>;
|
using resp3_handshaker_type = detail::resp3_handshaker<executor_type>;
|
||||||
|
|
||||||
auto use_ssl() const noexcept
|
auto use_ssl() const noexcept { return cfg_.use_ssl; }
|
||||||
{ return cfg_.use_ssl;}
|
|
||||||
|
|
||||||
void cancel_run()
|
void cancel_run()
|
||||||
{
|
{
|
||||||
@@ -813,20 +791,19 @@ private:
|
|||||||
template <class CompletionToken, class Logger>
|
template <class CompletionToken, class Logger>
|
||||||
auto reader(Logger l, CompletionToken&& token)
|
auto reader(Logger l, CompletionToken&& token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
detail::reader_op<this_type, Logger>{this, l},
|
||||||
, void(system::error_code)
|
std::forward<CompletionToken>(token),
|
||||||
>(detail::reader_op<this_type, Logger>{this, l},
|
writer_timer_);
|
||||||
std::forward<CompletionToken>(token), writer_timer_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class CompletionToken, class Logger>
|
template <class CompletionToken, class Logger>
|
||||||
auto writer(Logger l, CompletionToken&& token)
|
auto writer(Logger l, CompletionToken&& token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
detail::writer_op<this_type, Logger>{this, l},
|
||||||
, void(system::error_code)
|
std::forward<CompletionToken>(token),
|
||||||
>(detail::writer_op<this_type, Logger>{this, l}, std::forward<CompletionToken>(token), writer_timer_);
|
writer_timer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void close()
|
void close()
|
||||||
@@ -840,10 +817,7 @@ private:
|
|||||||
auto is_open() const noexcept { return stream_->next_layer().is_open(); }
|
auto is_open() const noexcept { return stream_->next_layer().is_open(); }
|
||||||
auto& lowest_layer() noexcept { return stream_->lowest_layer(); }
|
auto& lowest_layer() noexcept { return stream_->lowest_layer(); }
|
||||||
|
|
||||||
[[nodiscard]] bool trigger_write() const noexcept
|
[[nodiscard]] bool trigger_write() const noexcept { return is_open() && !mpx_.is_writing(); }
|
||||||
{
|
|
||||||
return is_open() && !mpx_.is_writing();
|
|
||||||
}
|
|
||||||
|
|
||||||
asio::ssl::context ctx_;
|
asio::ssl::context ctx_;
|
||||||
std::unique_ptr<next_layer_type> stream_;
|
std::unique_ptr<next_layer_type> stream_;
|
||||||
@@ -877,43 +851,41 @@ public:
|
|||||||
using executor_type = asio::any_io_executor;
|
using executor_type = asio::any_io_executor;
|
||||||
|
|
||||||
/// Contructs from an executor.
|
/// Contructs from an executor.
|
||||||
explicit
|
explicit connection(
|
||||||
connection(
|
|
||||||
executor_type ex,
|
executor_type ex,
|
||||||
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client});
|
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client});
|
||||||
|
|
||||||
/// Contructs from a context.
|
/// Contructs from a context.
|
||||||
explicit
|
explicit connection(
|
||||||
connection(
|
|
||||||
asio::io_context& ioc,
|
asio::io_context& ioc,
|
||||||
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client});
|
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client});
|
||||||
|
|
||||||
/// Returns the underlying executor.
|
/// Returns the underlying executor.
|
||||||
executor_type get_executor() noexcept
|
executor_type get_executor() noexcept { return impl_.get_executor(); }
|
||||||
{ return impl_.get_executor(); }
|
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::async_run`.
|
/// Calls `boost::redis::basic_connection::async_run`.
|
||||||
template <class CompletionToken = asio::deferred_t>
|
template <class CompletionToken = asio::deferred_t>
|
||||||
auto async_run(config const& cfg, logger l, CompletionToken&& token = {})
|
auto async_run(config const& cfg, logger l, CompletionToken&& token = {})
|
||||||
{
|
{
|
||||||
return asio::async_initiate<
|
return asio::async_initiate<CompletionToken, void(boost::system::error_code)>(
|
||||||
CompletionToken, void(boost::system::error_code)>(
|
[](auto handler, connection* self, config const* cfg, logger l) {
|
||||||
[](auto handler, connection* self, config const* cfg, logger l)
|
|
||||||
{
|
|
||||||
self->async_run_impl(*cfg, l, std::move(handler));
|
self->async_run_impl(*cfg, l, std::move(handler));
|
||||||
}, token, this, &cfg, l);
|
},
|
||||||
|
token,
|
||||||
|
this,
|
||||||
|
&cfg,
|
||||||
|
l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::async_receive`.
|
/// Calls `boost::redis::basic_connection::async_receive`.
|
||||||
template <class CompletionToken = asio::deferred_t>
|
template <class CompletionToken = asio::deferred_t>
|
||||||
auto async_receive(CompletionToken&& token = {})
|
auto async_receive(CompletionToken&& token = {})
|
||||||
{ return impl_.async_receive(std::forward<CompletionToken>(token)); }
|
{
|
||||||
|
return impl_.async_receive(std::forward<CompletionToken>(token));
|
||||||
|
}
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::receive`.
|
/// Calls `boost::redis::basic_connection::receive`.
|
||||||
std::size_t receive(system::error_code& ec)
|
std::size_t receive(system::error_code& ec) { return impl_.receive(ec); }
|
||||||
{
|
|
||||||
return impl_.receive(ec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::async_exec`.
|
/// Calls `boost::redis::basic_connection::async_exec`.
|
||||||
template <class Response, class CompletionToken = asio::deferred_t>
|
template <class Response, class CompletionToken = asio::deferred_t>
|
||||||
@@ -924,61 +896,53 @@ public:
|
|||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::async_exec`.
|
/// Calls `boost::redis::basic_connection::async_exec`.
|
||||||
template <class CompletionToken = asio::deferred_t>
|
template <class CompletionToken = asio::deferred_t>
|
||||||
auto
|
auto async_exec(request const& req, any_adapter adapter, CompletionToken&& token = {})
|
||||||
async_exec(
|
|
||||||
request const& req,
|
|
||||||
any_adapter adapter,
|
|
||||||
CompletionToken&& token = {})
|
|
||||||
{
|
|
||||||
return asio::async_initiate<
|
|
||||||
CompletionToken, void(boost::system::error_code, std::size_t)>(
|
|
||||||
[](auto handler, connection* self, request const* req, any_adapter&& adapter)
|
|
||||||
{
|
{
|
||||||
|
return asio::async_initiate<CompletionToken, void(boost::system::error_code, std::size_t)>(
|
||||||
|
[](auto handler, connection* self, request const* req, any_adapter&& adapter) {
|
||||||
self->async_exec_impl(*req, std::move(adapter), std::move(handler));
|
self->async_exec_impl(*req, std::move(adapter), std::move(handler));
|
||||||
}, token, this, &req, std::move(adapter));
|
},
|
||||||
|
token,
|
||||||
|
this,
|
||||||
|
&req,
|
||||||
|
std::move(adapter));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::cancel`.
|
/// Calls `boost::redis::basic_connection::cancel`.
|
||||||
void cancel(operation op = operation::all);
|
void cancel(operation op = operation::all);
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::will_reconnect`.
|
/// Calls `boost::redis::basic_connection::will_reconnect`.
|
||||||
bool will_reconnect() const noexcept
|
bool will_reconnect() const noexcept { return impl_.will_reconnect(); }
|
||||||
{ return impl_.will_reconnect();}
|
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::next_layer`.
|
/// Calls `boost::redis::basic_connection::next_layer`.
|
||||||
auto& next_layer() noexcept
|
auto& next_layer() noexcept { return impl_.next_layer(); }
|
||||||
{ return impl_.next_layer(); }
|
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::next_layer`.
|
/// Calls `boost::redis::basic_connection::next_layer`.
|
||||||
auto const& next_layer() const noexcept
|
auto const& next_layer() const noexcept { return impl_.next_layer(); }
|
||||||
{ return impl_.next_layer(); }
|
|
||||||
|
|
||||||
/// Calls `boost::redis::basic_connection::reset_stream`.
|
/// Calls `boost::redis::basic_connection::reset_stream`.
|
||||||
void reset_stream()
|
void reset_stream() { impl_.reset_stream(); }
|
||||||
{ impl_.reset_stream();}
|
|
||||||
|
|
||||||
/// Sets the response object of `async_receive` operations.
|
/// Sets the response object of `async_receive` operations.
|
||||||
template <class Response>
|
template <class Response>
|
||||||
void set_receive_response(Response& response)
|
void set_receive_response(Response& response)
|
||||||
{ impl_.set_receive_response(response); }
|
{
|
||||||
|
impl_.set_receive_response(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns connection usage information.
|
/// Returns connection usage information.
|
||||||
usage get_usage() const noexcept
|
usage get_usage() const noexcept { return impl_.get_usage(); }
|
||||||
{ return impl_.get_usage(); }
|
|
||||||
|
|
||||||
/// Returns the ssl context.
|
/// Returns the ssl context.
|
||||||
auto const& get_ssl_context() const noexcept
|
auto const& get_ssl_context() const noexcept { return impl_.get_ssl_context(); }
|
||||||
{ return impl_.get_ssl_context();}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
void async_run_impl(
|
||||||
async_run_impl(
|
|
||||||
config const& cfg,
|
config const& cfg,
|
||||||
logger l,
|
logger l,
|
||||||
asio::any_completion_handler<void(boost::system::error_code)> token);
|
asio::any_completion_handler<void(boost::system::error_code)> token);
|
||||||
|
|
||||||
void
|
void async_exec_impl(
|
||||||
async_exec_impl(
|
|
||||||
request const& req,
|
request const& req,
|
||||||
any_adapter&& adapter,
|
any_adapter&& adapter,
|
||||||
asio::any_completion_handler<void(boost::system::error_code, std::size_t)> token);
|
asio::any_completion_handler<void(boost::system::error_code, std::size_t)> token);
|
||||||
@@ -986,6 +950,6 @@ private:
|
|||||||
basic_connection<executor_type> impl_;
|
basic_connection<executor_type> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_CONNECTION_HPP
|
#endif // BOOST_REDIS_CONNECTION_HPP
|
||||||
|
|||||||
@@ -9,16 +9,17 @@
|
|||||||
|
|
||||||
#include <boost/redis/detail/helper.hpp>
|
#include <boost/redis/detail/helper.hpp>
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/cancel_after.hpp>
|
||||||
#include <boost/asio/compose.hpp>
|
#include <boost/asio/compose.hpp>
|
||||||
#include <boost/asio/connect.hpp>
|
#include <boost/asio/connect.hpp>
|
||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
#include <boost/asio/cancel_after.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
namespace boost::redis::detail
|
#include <chrono>
|
||||||
{
|
#include <string>
|
||||||
|
|
||||||
|
namespace boost::redis::detail {
|
||||||
|
|
||||||
template <class Connector, class Stream>
|
template <class Connector, class Stream>
|
||||||
struct connect_op {
|
struct connect_op {
|
||||||
@@ -28,15 +29,20 @@ struct connect_op {
|
|||||||
asio::coroutine coro{};
|
asio::coroutine coro{};
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()( Self& self
|
void operator()(
|
||||||
, system::error_code const& ec = {}
|
Self& self,
|
||||||
, asio::ip::tcp::endpoint const& ep= {})
|
system::error_code const& ec = {},
|
||||||
|
asio::ip::tcp::endpoint const& ep = {})
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro)
|
BOOST_ASIO_CORO_REENTER(coro)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
asio::async_connect(*stream, *res_,
|
asio::async_connect(
|
||||||
[](system::error_code const&, auto const&) { return true; },
|
*stream,
|
||||||
|
*res_,
|
||||||
|
[](system::error_code const&, auto const&) {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
asio::cancel_after(ctor_->timeout_, std::move(self)));
|
asio::cancel_after(ctor_->timeout_, std::move(self)));
|
||||||
|
|
||||||
ctor_->endpoint_ = ep;
|
ctor_->endpoint_ = ep;
|
||||||
@@ -52,23 +58,20 @@ struct connect_op {
|
|||||||
|
|
||||||
class connector {
|
class connector {
|
||||||
public:
|
public:
|
||||||
void set_config(config const& cfg)
|
void set_config(config const& cfg) { timeout_ = cfg.connect_timeout; }
|
||||||
{ timeout_ = cfg.connect_timeout; }
|
|
||||||
|
|
||||||
template <class Stream, class CompletionToken>
|
template <class Stream, class CompletionToken>
|
||||||
auto
|
auto async_connect(
|
||||||
async_connect(
|
|
||||||
Stream& stream,
|
Stream& stream,
|
||||||
asio::ip::tcp::resolver::results_type const& res,
|
asio::ip::tcp::resolver::results_type const& res,
|
||||||
CompletionToken&& token)
|
CompletionToken&& token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
connect_op<connector, Stream>{this, &stream, &res},
|
||||||
, void(system::error_code)
|
token);
|
||||||
>(connect_op<connector, Stream>{this, &stream, &res}, token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const& endpoint() const noexcept { return endpoint_;}
|
auto const& endpoint() const noexcept { return endpoint_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class, class> friend struct connect_op;
|
template <class, class> friend struct connect_op;
|
||||||
@@ -77,6 +80,6 @@ private:
|
|||||||
asio::ip::tcp::endpoint endpoint_;
|
asio::ip::tcp::endpoint endpoint_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_CONNECTOR_HPP
|
#endif // BOOST_REDIS_CONNECTOR_HPP
|
||||||
|
|||||||
@@ -7,19 +7,20 @@
|
|||||||
#ifndef BOOST_REDIS_HEALTH_CHECKER_HPP
|
#ifndef BOOST_REDIS_HEALTH_CHECKER_HPP
|
||||||
#define BOOST_REDIS_HEALTH_CHECKER_HPP
|
#define BOOST_REDIS_HEALTH_CHECKER_HPP
|
||||||
|
|
||||||
#include <boost/redis/request.hpp>
|
|
||||||
#include <boost/redis/response.hpp>
|
|
||||||
#include <boost/redis/operation.hpp>
|
|
||||||
#include <boost/redis/adapter/any_adapter.hpp>
|
#include <boost/redis/adapter/any_adapter.hpp>
|
||||||
#include <boost/redis/config.hpp>
|
#include <boost/redis/config.hpp>
|
||||||
#include <boost/redis/operation.hpp>
|
#include <boost/redis/operation.hpp>
|
||||||
#include <boost/asio/steady_timer.hpp>
|
#include <boost/redis/request.hpp>
|
||||||
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
#include <boost/asio/compose.hpp>
|
#include <boost/asio/compose.hpp>
|
||||||
#include <boost/asio/consign.hpp>
|
#include <boost/asio/consign.hpp>
|
||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
#include <boost/asio/post.hpp>
|
#include <boost/asio/post.hpp>
|
||||||
#include <memory>
|
#include <boost/asio/steady_timer.hpp>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace boost::redis::detail {
|
namespace boost::redis::detail {
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ public:
|
|||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()(Self& self, system::error_code ec = {}, std::size_t = 0)
|
void operator()(Self& self, system::error_code ec = {}, std::size_t = 0)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_) for (;;)
|
BOOST_ASIO_CORO_REENTER(coro_) for (;;)
|
||||||
{
|
{
|
||||||
if (checker_->ping_interval_ == std::chrono::seconds::zero()) {
|
if (checker_->ping_interval_ == std::chrono::seconds::zero()) {
|
||||||
logger_.trace("ping_op (1): timeout disabled.");
|
logger_.trace("ping_op (1): timeout disabled.");
|
||||||
@@ -84,7 +85,7 @@ public:
|
|||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()(Self& self, system::error_code ec = {})
|
void operator()(Self& self, system::error_code ec = {})
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_) for (;;)
|
BOOST_ASIO_CORO_REENTER(coro_) for (;;)
|
||||||
{
|
{
|
||||||
if (checker_->ping_interval_ == std::chrono::seconds::zero()) {
|
if (checker_->ping_interval_ == std::chrono::seconds::zero()) {
|
||||||
logger_.trace("check_timeout_op (1): timeout disabled.");
|
logger_.trace("check_timeout_op (1): timeout disabled.");
|
||||||
@@ -130,8 +131,7 @@ public:
|
|||||||
template <class Executor>
|
template <class Executor>
|
||||||
class health_checker {
|
class health_checker {
|
||||||
private:
|
private:
|
||||||
using timer_type =
|
using timer_type = asio::basic_waitable_timer<
|
||||||
asio::basic_waitable_timer<
|
|
||||||
std::chrono::steady_clock,
|
std::chrono::steady_clock,
|
||||||
asio::wait_traits<std::chrono::steady_clock>,
|
asio::wait_traits<std::chrono::steady_clock>,
|
||||||
Executor>;
|
Executor>;
|
||||||
@@ -160,20 +160,22 @@ public:
|
|||||||
template <class Connection, class Logger, class CompletionToken>
|
template <class Connection, class Logger, class CompletionToken>
|
||||||
auto async_ping(Connection& conn, Logger l, CompletionToken token)
|
auto async_ping(Connection& conn, Logger l, CompletionToken token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
ping_op<health_checker, Connection, Logger>{this, &conn, l},
|
||||||
, void(system::error_code)
|
token,
|
||||||
>(ping_op<health_checker, Connection, Logger>{this, &conn, l}, token, conn, ping_timer_);
|
conn,
|
||||||
|
ping_timer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Connection, class Logger, class CompletionToken>
|
template <class Connection, class Logger, class CompletionToken>
|
||||||
auto async_check_timeout(Connection& conn, Logger l, CompletionToken token)
|
auto async_check_timeout(Connection& conn, Logger l, CompletionToken token)
|
||||||
{
|
{
|
||||||
checker_has_exited_ = false;
|
checker_has_exited_ = false;
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
check_timeout_op<health_checker, Connection, Logger>{this, &conn, l},
|
||||||
, void(system::error_code)
|
token,
|
||||||
>(check_timeout_op<health_checker, Connection, Logger>{this, &conn, l}, token, conn, wait_timer_);
|
conn,
|
||||||
|
wait_timer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -188,6 +190,6 @@ private:
|
|||||||
bool checker_has_exited_ = false;
|
bool checker_has_exited_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_HEALTH_CHECKER_HPP
|
#endif // BOOST_REDIS_HEALTH_CHECKER_HPP
|
||||||
|
|||||||
@@ -9,8 +9,7 @@
|
|||||||
|
|
||||||
#include <boost/asio/cancellation_type.hpp>
|
#include <boost/asio/cancellation_type.hpp>
|
||||||
|
|
||||||
namespace boost::redis::detail
|
namespace boost::redis::detail {
|
||||||
{
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
auto is_cancelled(T const& self)
|
auto is_cancelled(T const& self)
|
||||||
@@ -18,20 +17,18 @@ auto is_cancelled(T const& self)
|
|||||||
return self.get_cancellation_state().cancelled() != asio::cancellation_type_t::none;
|
return self.get_cancellation_state().cancelled() != asio::cancellation_type_t::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BOOST_REDIS_CHECK_OP0(X)\
|
#define BOOST_REDIS_CHECK_OP0(X) \
|
||||||
if (ec || redis::detail::is_cancelled(self)) {\
|
if (ec || redis::detail::is_cancelled(self)) { \
|
||||||
X\
|
X self.complete(!!ec ? ec : asio::error::operation_aborted); \
|
||||||
self.complete(!!ec ? ec : asio::error::operation_aborted);\
|
return; \
|
||||||
return;\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BOOST_REDIS_CHECK_OP1(X)\
|
#define BOOST_REDIS_CHECK_OP1(X) \
|
||||||
if (ec || redis::detail::is_cancelled(self)) {\
|
if (ec || redis::detail::is_cancelled(self)) { \
|
||||||
X\
|
X self.complete(!!ec ? ec : asio::error::operation_aborted, {}); \
|
||||||
self.complete(!!ec ? ec : asio::error::operation_aborted, {});\
|
return; \
|
||||||
return;\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_HELPER_HPP
|
#endif // BOOST_REDIS_HELPER_HPP
|
||||||
|
|||||||
@@ -20,12 +20,11 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
class request;
|
class request;
|
||||||
|
|
||||||
@@ -35,63 +34,61 @@ using tribool = std::optional<bool>;
|
|||||||
|
|
||||||
struct multiplexer {
|
struct multiplexer {
|
||||||
using adapter_type = std::function<void(resp3::node_view const&, system::error_code&)>;
|
using adapter_type = std::function<void(resp3::node_view const&, system::error_code&)>;
|
||||||
using pipeline_adapter_type = std::function<void(std::size_t, resp3::node_view const&, system::error_code&)>;
|
using pipeline_adapter_type = std::function<
|
||||||
|
void(std::size_t, resp3::node_view const&, system::error_code&)>;
|
||||||
|
|
||||||
struct elem {
|
struct elem {
|
||||||
public:
|
public:
|
||||||
explicit elem(request const& req, pipeline_adapter_type adapter);
|
explicit elem(request const& req, pipeline_adapter_type adapter);
|
||||||
|
|
||||||
void set_done_callback(std::function<void()> f) noexcept
|
void set_done_callback(std::function<void()> f) noexcept { done_ = std::move(f); };
|
||||||
{ done_ = std::move(f); };
|
|
||||||
|
|
||||||
auto notify_done() noexcept
|
auto notify_done() noexcept { done_(); }
|
||||||
{ done_(); }
|
|
||||||
|
|
||||||
auto notify_error(system::error_code ec) noexcept -> void;
|
auto notify_error(system::error_code ec) noexcept -> void;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto is_waiting() const noexcept
|
auto is_waiting() const noexcept
|
||||||
{ return status_ == status::waiting; }
|
{
|
||||||
|
return status_ == status::waiting;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto is_written() const noexcept
|
auto is_written() const noexcept
|
||||||
{ return status_ == status::written; }
|
{
|
||||||
|
return status_ == status::written;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto is_staged() const noexcept
|
auto is_staged() const noexcept
|
||||||
{ return status_ == status::staged; }
|
{
|
||||||
|
return status_ == status::staged;
|
||||||
|
}
|
||||||
|
|
||||||
void mark_written() noexcept
|
void mark_written() noexcept { status_ = status::written; }
|
||||||
{ status_ = status::written; }
|
|
||||||
|
|
||||||
void mark_staged() noexcept
|
void mark_staged() noexcept { status_ = status::staged; }
|
||||||
{ status_ = status::staged; }
|
|
||||||
|
|
||||||
void mark_waiting() noexcept
|
void mark_waiting() noexcept { status_ = status::waiting; }
|
||||||
{ status_ = status::waiting; }
|
|
||||||
|
|
||||||
auto get_error() const -> system::error_code const&
|
auto get_error() const -> system::error_code const& { return ec_; }
|
||||||
{ return ec_; }
|
|
||||||
|
|
||||||
auto get_request() const -> request const&
|
auto get_request() const -> request const& { return *req_; }
|
||||||
{ return *req_; }
|
|
||||||
|
|
||||||
auto get_read_size() const -> std::size_t
|
auto get_read_size() const -> std::size_t { return read_size_; }
|
||||||
{ return read_size_; }
|
|
||||||
|
|
||||||
auto get_remaining_responses() const -> std::size_t
|
auto get_remaining_responses() const -> std::size_t { return remaining_responses_; }
|
||||||
{ return remaining_responses_; }
|
|
||||||
|
|
||||||
auto commit_response(std::size_t read_size) -> void;
|
auto commit_response(std::size_t read_size) -> void;
|
||||||
|
|
||||||
auto get_adapter() -> adapter_type&
|
auto get_adapter() -> adapter_type& { return adapter_; }
|
||||||
{ return adapter_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class status
|
enum class status
|
||||||
{ waiting
|
{
|
||||||
, staged
|
waiting,
|
||||||
, written
|
staged,
|
||||||
|
written
|
||||||
};
|
};
|
||||||
|
|
||||||
request const* req_;
|
request const* req_;
|
||||||
@@ -124,7 +121,9 @@ struct multiplexer {
|
|||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto const& get_parser() const noexcept
|
auto const& get_parser() const noexcept
|
||||||
{ return parser_; }
|
{
|
||||||
|
return parser_;
|
||||||
|
}
|
||||||
|
|
||||||
//[[nodiscard]]
|
//[[nodiscard]]
|
||||||
auto cancel_waiting() -> std::size_t;
|
auto cancel_waiting() -> std::size_t;
|
||||||
@@ -134,19 +133,27 @@ struct multiplexer {
|
|||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_cancel_run_state() const noexcept -> bool
|
auto get_cancel_run_state() const noexcept -> bool
|
||||||
{ return cancel_run_called_; }
|
{
|
||||||
|
return cancel_run_called_;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_write_buffer() noexcept -> std::string_view
|
auto get_write_buffer() noexcept -> std::string_view
|
||||||
{ return std::string_view{write_buffer_}; }
|
{
|
||||||
|
return std::string_view{write_buffer_};
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_read_buffer() noexcept -> std::string&
|
auto get_read_buffer() noexcept -> std::string&
|
||||||
{ return read_buffer_; }
|
{
|
||||||
|
return read_buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto is_data_needed() const noexcept -> bool
|
auto is_data_needed() const noexcept -> bool
|
||||||
{ return std::empty(read_buffer_); }
|
{
|
||||||
|
return std::empty(read_buffer_);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Change signature to receive an adapter instead of a
|
// TODO: Change signature to receive an adapter instead of a
|
||||||
// response.
|
// response.
|
||||||
@@ -160,7 +167,9 @@ struct multiplexer {
|
|||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_usage() const noexcept -> usage
|
auto get_usage() const noexcept -> usage
|
||||||
{ return usage_;}
|
{
|
||||||
|
return usage_;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto is_writing() const noexcept -> bool;
|
auto is_writing() const noexcept -> bool;
|
||||||
@@ -189,12 +198,10 @@ private:
|
|||||||
adapter_type receive_adapter_;
|
adapter_type receive_adapter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto
|
auto make_elem(request const& req, multiplexer::pipeline_adapter_type adapter)
|
||||||
make_elem(
|
-> std::shared_ptr<multiplexer::elem>;
|
||||||
request const& req,
|
|
||||||
multiplexer::pipeline_adapter_type adapter) -> std::shared_ptr<multiplexer::elem>;
|
|
||||||
|
|
||||||
} // detail
|
} // namespace detail
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_MULTIPLEXER_HPP
|
#endif // BOOST_REDIS_MULTIPLEXER_HPP
|
||||||
|
|||||||
@@ -9,15 +9,16 @@
|
|||||||
|
|
||||||
#include <boost/redis/config.hpp>
|
#include <boost/redis/config.hpp>
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/cancel_after.hpp>
|
||||||
#include <boost/asio/compose.hpp>
|
#include <boost/asio/compose.hpp>
|
||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
#include <boost/asio/cancel_after.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
namespace boost::redis::detail
|
#include <chrono>
|
||||||
{
|
#include <string>
|
||||||
|
|
||||||
|
namespace boost::redis::detail {
|
||||||
|
|
||||||
template <class Resolver>
|
template <class Resolver>
|
||||||
struct resolve_op {
|
struct resolve_op {
|
||||||
@@ -25,11 +26,12 @@ struct resolve_op {
|
|||||||
asio::coroutine coro{};
|
asio::coroutine coro{};
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()( Self& self
|
void operator()(
|
||||||
, system::error_code ec = {}
|
Self& self,
|
||||||
, asio::ip::tcp::resolver::results_type res = {})
|
system::error_code ec = {},
|
||||||
|
asio::ip::tcp::resolver::results_type res = {})
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro)
|
BOOST_ASIO_CORO_REENTER(coro)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
resv_->resv_.async_resolve(
|
resv_->resv_.async_resolve(
|
||||||
@@ -51,22 +53,22 @@ struct resolve_op {
|
|||||||
template <class Executor>
|
template <class Executor>
|
||||||
class resolver {
|
class resolver {
|
||||||
public:
|
public:
|
||||||
resolver(Executor ex) : resv_{ex} {}
|
resolver(Executor ex)
|
||||||
|
: resv_{ex}
|
||||||
|
{ }
|
||||||
|
|
||||||
template <class CompletionToken>
|
template <class CompletionToken>
|
||||||
auto async_resolve(CompletionToken&& token)
|
auto async_resolve(CompletionToken&& token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
resolve_op<resolver>{this},
|
||||||
, void(system::error_code)
|
token,
|
||||||
>(resolve_op<resolver>{this}, token, resv_);
|
resv_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cancel()
|
void cancel() { resv_.cancel(); }
|
||||||
{ resv_.cancel(); }
|
|
||||||
|
|
||||||
auto const& results() const noexcept
|
auto const& results() const noexcept { return results_; }
|
||||||
{ return results_;}
|
|
||||||
|
|
||||||
void set_config(config const& cfg)
|
void set_config(config const& cfg)
|
||||||
{
|
{
|
||||||
@@ -84,6 +86,6 @@ private:
|
|||||||
asio::ip::tcp::resolver::results_type results_;
|
asio::ip::tcp::resolver::results_type results_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RESOLVER_HPP
|
#endif // BOOST_REDIS_RESOLVER_HPP
|
||||||
|
|||||||
@@ -8,20 +8,20 @@
|
|||||||
#define BOOST_REDIS_RUNNER_HPP
|
#define BOOST_REDIS_RUNNER_HPP
|
||||||
|
|
||||||
#include <boost/redis/config.hpp>
|
#include <boost/redis/config.hpp>
|
||||||
#include <boost/redis/request.hpp>
|
|
||||||
#include <boost/redis/response.hpp>
|
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
#include <boost/redis/operation.hpp>
|
#include <boost/redis/operation.hpp>
|
||||||
|
#include <boost/redis/request.hpp>
|
||||||
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
#include <boost/asio/compose.hpp>
|
#include <boost/asio/compose.hpp>
|
||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
//#include <boost/asio/ip/tcp.hpp>
|
//#include <boost/asio/ip/tcp.hpp>
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace boost::redis::detail
|
namespace boost::redis::detail {
|
||||||
{
|
|
||||||
|
|
||||||
void push_hello(config const& cfg, request& req);
|
void push_hello(config const& cfg, request& req);
|
||||||
|
|
||||||
@@ -38,12 +38,15 @@ struct hello_op {
|
|||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()(Self& self, system::error_code ec = {}, std::size_t = 0)
|
void operator()(Self& self, system::error_code ec = {}, std::size_t = 0)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_)
|
BOOST_ASIO_CORO_REENTER(coro_)
|
||||||
{
|
{
|
||||||
handshaker_->add_hello();
|
handshaker_->add_hello();
|
||||||
|
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
conn_->async_exec(handshaker_->hello_req_, any_adapter(handshaker_->hello_resp_), std::move(self));
|
conn_->async_exec(
|
||||||
|
handshaker_->hello_req_,
|
||||||
|
any_adapter(handshaker_->hello_resp_),
|
||||||
|
std::move(self));
|
||||||
logger_.on_hello(ec, handshaker_->hello_resp_);
|
logger_.on_hello(ec, handshaker_->hello_resp_);
|
||||||
|
|
||||||
if (ec) {
|
if (ec) {
|
||||||
@@ -66,16 +69,15 @@ struct hello_op {
|
|||||||
template <class Executor>
|
template <class Executor>
|
||||||
class resp3_handshaker {
|
class resp3_handshaker {
|
||||||
public:
|
public:
|
||||||
void set_config(config const& cfg)
|
void set_config(config const& cfg) { cfg_ = cfg; }
|
||||||
{ cfg_ = cfg; }
|
|
||||||
|
|
||||||
template <class Connection, class Logger, class CompletionToken>
|
template <class Connection, class Logger, class CompletionToken>
|
||||||
auto async_hello(Connection& conn, Logger l, CompletionToken token)
|
auto async_hello(Connection& conn, Logger l, CompletionToken token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
hello_op<resp3_handshaker, Connection, Logger>{this, &conn, l},
|
||||||
, void(system::error_code)
|
token,
|
||||||
>(hello_op<resp3_handshaker, Connection, Logger>{this, &conn, l}, token, conn);
|
conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -94,8 +96,7 @@ private:
|
|||||||
if (!hello_resp_.has_value())
|
if (!hello_resp_.has_value())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto f = [](auto const& e)
|
auto f = [](auto const& e) {
|
||||||
{
|
|
||||||
switch (e.data_type) {
|
switch (e.data_type) {
|
||||||
case resp3::type::simple_error:
|
case resp3::type::simple_error:
|
||||||
case resp3::type::blob_error: return true;
|
case resp3::type::blob_error: return true;
|
||||||
@@ -111,6 +112,6 @@ private:
|
|||||||
config cfg_;
|
config cfg_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RUNNER_HPP
|
#endif // BOOST_REDIS_RUNNER_HPP
|
||||||
|
|||||||
@@ -9,26 +9,27 @@
|
|||||||
|
|
||||||
#include <boost/redis/adapter/any_adapter.hpp>
|
#include <boost/redis/adapter/any_adapter.hpp>
|
||||||
#include <boost/redis/config.hpp>
|
#include <boost/redis/config.hpp>
|
||||||
#include <boost/redis/request.hpp>
|
|
||||||
#include <boost/redis/response.hpp>
|
|
||||||
#include <boost/redis/detail/helper.hpp>
|
#include <boost/redis/detail/helper.hpp>
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
#include <boost/redis/operation.hpp>
|
#include <boost/redis/operation.hpp>
|
||||||
|
#include <boost/redis/request.hpp>
|
||||||
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/cancel_after.hpp>
|
||||||
#include <boost/asio/compose.hpp>
|
#include <boost/asio/compose.hpp>
|
||||||
#include <boost/asio/coroutine.hpp>
|
#include <boost/asio/coroutine.hpp>
|
||||||
#include <boost/asio/experimental/parallel_group.hpp>
|
#include <boost/asio/experimental/parallel_group.hpp>
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
#include <boost/asio/steady_timer.hpp>
|
|
||||||
#include <boost/asio/prepend.hpp>
|
#include <boost/asio/prepend.hpp>
|
||||||
#include <boost/asio/ssl.hpp>
|
#include <boost/asio/ssl.hpp>
|
||||||
#include <boost/asio/cancel_after.hpp>
|
#include <boost/asio/steady_timer.hpp>
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
namespace boost::redis::detail
|
#include <chrono>
|
||||||
{
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace boost::redis::detail {
|
||||||
|
|
||||||
void push_hello(config const& cfg, request& req);
|
void push_hello(config const& cfg, request& req);
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ struct hello_op {
|
|||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()(Self& self, system::error_code ec = {}, std::size_t = 0)
|
void operator()(Self& self, system::error_code ec = {}, std::size_t = 0)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_)
|
BOOST_ASIO_CORO_REENTER(coro_)
|
||||||
{
|
{
|
||||||
runner_->add_hello();
|
runner_->add_hello();
|
||||||
|
|
||||||
@@ -85,21 +86,22 @@ public:
|
|||||||
: runner_{runner}
|
: runner_{runner}
|
||||||
, conn_{conn}
|
, conn_{conn}
|
||||||
, logger_{l}
|
, logger_{l}
|
||||||
{}
|
{ }
|
||||||
|
|
||||||
template <class Self>
|
template <class Self>
|
||||||
void operator()( Self& self
|
void operator()(
|
||||||
, order_t order = {}
|
Self& self,
|
||||||
, system::error_code ec0 = {}
|
order_t order = {},
|
||||||
, system::error_code ec1 = {}
|
system::error_code ec0 = {},
|
||||||
, system::error_code ec2 = {}
|
system::error_code ec1 = {},
|
||||||
, system::error_code ec3 = {}
|
system::error_code ec2 = {},
|
||||||
, system::error_code ec4 = {})
|
system::error_code ec3 = {},
|
||||||
|
system::error_code ec4 = {})
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro_) for (;;)
|
BOOST_ASIO_CORO_REENTER(coro_) for (;;)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
conn_->resv_.async_resolve(asio::prepend(std::move(self), order_t {}));
|
conn_->resv_.async_resolve(asio::prepend(std::move(self), order_t{}));
|
||||||
|
|
||||||
logger_.on_resolve(ec0, conn_->resv_.results());
|
logger_.on_resolve(ec0, conn_->resv_.results());
|
||||||
|
|
||||||
@@ -112,7 +114,7 @@ public:
|
|||||||
conn_->ctor_.async_connect(
|
conn_->ctor_.async_connect(
|
||||||
conn_->next_layer().next_layer(),
|
conn_->next_layer().next_layer(),
|
||||||
conn_->resv_.results(),
|
conn_->resv_.results(),
|
||||||
asio::prepend(std::move(self), order_t {}));
|
asio::prepend(std::move(self), order_t{}));
|
||||||
|
|
||||||
logger_.on_connect(ec0, conn_->ctor_.endpoint());
|
logger_.on_connect(ec0, conn_->ctor_.endpoint());
|
||||||
|
|
||||||
@@ -126,13 +128,8 @@ public:
|
|||||||
conn_->next_layer().async_handshake(
|
conn_->next_layer().async_handshake(
|
||||||
asio::ssl::stream_base::client,
|
asio::ssl::stream_base::client,
|
||||||
asio::prepend(
|
asio::prepend(
|
||||||
asio::cancel_after(
|
asio::cancel_after(runner_->cfg_.ssl_handshake_timeout, std::move(self)),
|
||||||
runner_->cfg_.ssl_handshake_timeout,
|
order_t{}));
|
||||||
std::move(self)
|
|
||||||
),
|
|
||||||
order_t {}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
logger_.on_ssl_handshake(ec0);
|
logger_.on_ssl_handshake(ec0);
|
||||||
|
|
||||||
@@ -149,14 +146,22 @@ public:
|
|||||||
// causing an authentication problem.
|
// causing an authentication problem.
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
asio::experimental::make_parallel_group(
|
asio::experimental::make_parallel_group(
|
||||||
[this](auto token) { return runner_->async_hello(*conn_, logger_, token); },
|
[this](auto token) {
|
||||||
[this](auto token) { return conn_->health_checker_.async_ping(*conn_, logger_, token); },
|
return runner_->async_hello(*conn_, logger_, token);
|
||||||
[this](auto token) { return conn_->health_checker_.async_check_timeout(*conn_, logger_, token);},
|
},
|
||||||
[this](auto token) { return conn_->reader(logger_, token);},
|
[this](auto token) {
|
||||||
[this](auto token) { return conn_->writer(logger_, token);}
|
return conn_->health_checker_.async_ping(*conn_, logger_, token);
|
||||||
).async_wait(
|
},
|
||||||
asio::experimental::wait_for_one_error(),
|
[this](auto token) {
|
||||||
std::move(self));
|
return conn_->health_checker_.async_check_timeout(*conn_, logger_, token);
|
||||||
|
},
|
||||||
|
[this](auto token) {
|
||||||
|
return conn_->reader(logger_, token);
|
||||||
|
},
|
||||||
|
[this](auto token) {
|
||||||
|
return conn_->writer(logger_, token);
|
||||||
|
})
|
||||||
|
.async_wait(asio::experimental::wait_for_one_error(), std::move(self));
|
||||||
|
|
||||||
if (order[0] == 0 && !!ec0) {
|
if (order[0] == 0 && !!ec0) {
|
||||||
self.complete(ec0);
|
self.complete(ec0);
|
||||||
@@ -184,7 +189,7 @@ public:
|
|||||||
conn_->writer_timer_.expires_after(conn_->cfg_.reconnect_wait_interval);
|
conn_->writer_timer_.expires_after(conn_->cfg_.reconnect_wait_interval);
|
||||||
|
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
conn_->writer_timer_.async_wait(asio::prepend(std::move(self), order_t {}));
|
conn_->writer_timer_.async_wait(asio::prepend(std::move(self), order_t{}));
|
||||||
if (ec0) {
|
if (ec0) {
|
||||||
self.complete(ec0);
|
self.complete(ec0);
|
||||||
return;
|
return;
|
||||||
@@ -207,32 +212,28 @@ public:
|
|||||||
: cfg_{cfg}
|
: cfg_{cfg}
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void set_config(config const& cfg)
|
void set_config(config const& cfg) { cfg_ = cfg; }
|
||||||
{
|
|
||||||
cfg_ = cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Connection, class Logger, class CompletionToken>
|
template <class Connection, class Logger, class CompletionToken>
|
||||||
auto async_run(Connection& conn, Logger l, CompletionToken token)
|
auto async_run(Connection& conn, Logger l, CompletionToken token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
runner_op<runner, Connection, Logger>{this, &conn, l},
|
||||||
, void(system::error_code)
|
token,
|
||||||
>(runner_op<runner, Connection, Logger>{this, &conn, l}, token, conn);
|
conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template <class, class, class> friend class runner_op;
|
template <class, class, class> friend class runner_op;
|
||||||
template <class, class, class> friend struct hello_op;
|
template <class, class, class> friend struct hello_op;
|
||||||
|
|
||||||
template <class Connection, class Logger, class CompletionToken>
|
template <class Connection, class Logger, class CompletionToken>
|
||||||
auto async_hello(Connection& conn, Logger l, CompletionToken token)
|
auto async_hello(Connection& conn, Logger l, CompletionToken token)
|
||||||
{
|
{
|
||||||
return asio::async_compose
|
return asio::async_compose<CompletionToken, void(system::error_code)>(
|
||||||
< CompletionToken
|
hello_op<runner, Connection, Logger>{this, &conn, l},
|
||||||
, void(system::error_code)
|
token,
|
||||||
>(hello_op<runner, Connection, Logger>{this, &conn, l}, token, conn);
|
conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_hello()
|
void add_hello()
|
||||||
@@ -248,8 +249,7 @@ private:
|
|||||||
if (!hello_resp_.has_value())
|
if (!hello_resp_.has_value())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto f = [](auto const& e)
|
auto f = [](auto const& e) {
|
||||||
{
|
|
||||||
switch (e.data_type) {
|
switch (e.data_type) {
|
||||||
case resp3::type::simple_error:
|
case resp3::type::simple_error:
|
||||||
case resp3::type::blob_error: return true;
|
case resp3::type::blob_error: return true;
|
||||||
@@ -265,6 +265,6 @@ private:
|
|||||||
config cfg_;
|
config cfg_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RUNNER_HPP
|
#endif // BOOST_REDIS_RUNNER_HPP
|
||||||
|
|||||||
@@ -7,9 +7,10 @@
|
|||||||
#ifndef BOOST_REDIS_WRITE_HPP
|
#ifndef BOOST_REDIS_WRITE_HPP
|
||||||
#define BOOST_REDIS_WRITE_HPP
|
#define BOOST_REDIS_WRITE_HPP
|
||||||
|
|
||||||
#include <boost/asio/write.hpp>
|
|
||||||
#include <boost/redis/request.hpp>
|
#include <boost/redis/request.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/write.hpp>
|
||||||
|
|
||||||
namespace boost::redis::detail {
|
namespace boost::redis::detail {
|
||||||
|
|
||||||
/** \brief Writes a request synchronously.
|
/** \brief Writes a request synchronously.
|
||||||
@@ -18,13 +19,13 @@ namespace boost::redis::detail {
|
|||||||
* \param stream Stream to write the request to.
|
* \param stream Stream to write the request to.
|
||||||
* \param req Request to write.
|
* \param req Request to write.
|
||||||
*/
|
*/
|
||||||
template<class SyncWriteStream>
|
template <class SyncWriteStream>
|
||||||
auto write(SyncWriteStream& stream, request const& req)
|
auto write(SyncWriteStream& stream, request const& req)
|
||||||
{
|
{
|
||||||
return asio::write(stream, asio::buffer(req.payload()));
|
return asio::write(stream, asio::buffer(req.payload()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SyncWriteStream>
|
template <class SyncWriteStream>
|
||||||
auto write(SyncWriteStream& stream, request const& req, system::error_code& ec)
|
auto write(SyncWriteStream& stream, request const& req, system::error_code& ec)
|
||||||
{
|
{
|
||||||
return asio::write(stream, asio::buffer(req.payload()), ec);
|
return asio::write(stream, asio::buffer(req.payload()), ec);
|
||||||
@@ -37,10 +38,10 @@ auto write(SyncWriteStream& stream, request const& req, system::error_code& ec)
|
|||||||
* \param req Request to write.
|
* \param req Request to write.
|
||||||
* \param token Asio completion token.
|
* \param token Asio completion token.
|
||||||
*/
|
*/
|
||||||
template<
|
template <
|
||||||
class AsyncWriteStream,
|
class AsyncWriteStream,
|
||||||
class CompletionToken = asio::default_completion_token_t<typename AsyncWriteStream::executor_type>
|
class CompletionToken =
|
||||||
>
|
asio::default_completion_token_t<typename AsyncWriteStream::executor_type> >
|
||||||
auto async_write(
|
auto async_write(
|
||||||
AsyncWriteStream& stream,
|
AsyncWriteStream& stream,
|
||||||
request const& req,
|
request const& req,
|
||||||
@@ -50,6 +51,6 @@ auto async_write(
|
|||||||
return asio::async_write(stream, asio::buffer(req.payload()), token);
|
return asio::async_write(stream, asio::buffer(req.payload()), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|
||||||
#endif // BOOST_REDIS_WRITE_HPP
|
#endif // BOOST_REDIS_WRITE_HPP
|
||||||
|
|||||||
@@ -93,13 +93,13 @@ enum class error
|
|||||||
*/
|
*/
|
||||||
auto make_error_code(error e) -> system::error_code;
|
auto make_error_code(error e) -> system::error_code;
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
struct is_error_code_enum<::boost::redis::error> : std::true_type {};
|
struct is_error_code_enum<::boost::redis::error> : std::true_type { };
|
||||||
|
|
||||||
} // std
|
} // namespace std
|
||||||
|
|
||||||
#endif // BOOST_REDIS_ERROR_HPP
|
#endif // BOOST_REDIS_ERROR_HPP
|
||||||
|
|||||||
@@ -13,8 +13,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
/** @brief Type used to ignore responses.
|
/** @brief Type used to ignore responses.
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -44,6 +43,6 @@ using ignore_t = std::decay_t<decltype(std::ignore)>;
|
|||||||
*/
|
*/
|
||||||
extern ignore_t ignore;
|
extern ignore_t ignore;
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_IGNORE_HPP
|
#endif // BOOST_REDIS_IGNORE_HPP
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace boost::redis {
|
namespace boost::redis {
|
||||||
@@ -17,8 +18,7 @@ connection::connection(asio::io_context& ioc, asio::ssl::context ctx)
|
|||||||
: impl_{ioc.get_executor(), std::move(ctx)}
|
: impl_{ioc.get_executor(), std::move(ctx)}
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void
|
void connection::async_run_impl(
|
||||||
connection::async_run_impl(
|
|
||||||
config const& cfg,
|
config const& cfg,
|
||||||
logger l,
|
logger l,
|
||||||
asio::any_completion_handler<void(boost::system::error_code)> token)
|
asio::any_completion_handler<void(boost::system::error_code)> token)
|
||||||
@@ -26,8 +26,7 @@ connection::async_run_impl(
|
|||||||
impl_.async_run(cfg, l, std::move(token));
|
impl_.async_run(cfg, l, std::move(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void connection::async_exec_impl(
|
||||||
connection::async_exec_impl(
|
|
||||||
request const& req,
|
request const& req,
|
||||||
any_adapter&& adapter,
|
any_adapter&& adapter,
|
||||||
asio::any_completion_handler<void(boost::system::error_code, std::size_t)> token)
|
asio::any_completion_handler<void(boost::system::error_code, std::size_t)> token)
|
||||||
@@ -35,9 +34,6 @@ connection::async_exec_impl(
|
|||||||
impl_.async_exec(req, std::move(adapter), std::move(token));
|
impl_.async_exec(req, std::move(adapter), std::move(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
void connection::cancel(operation op)
|
void connection::cancel(operation op) { impl_.cancel(op); }
|
||||||
{
|
|
||||||
impl_.cancel(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost::redis
|
} // namespace boost::redis
|
||||||
|
|||||||
@@ -5,26 +5,25 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
namespace boost::redis {
|
namespace boost::redis {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
struct error_category_impl : system::error_category {
|
struct error_category_impl : system::error_category {
|
||||||
|
|
||||||
virtual ~error_category_impl() = default;
|
virtual ~error_category_impl() = default;
|
||||||
|
|
||||||
auto name() const noexcept -> char const* override
|
auto name() const noexcept -> char const* override { return "boost.redis"; }
|
||||||
{
|
|
||||||
return "boost.redis";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto message(int ev) const -> std::string override
|
auto message(int ev) const -> std::string override
|
||||||
{
|
{
|
||||||
switch(static_cast<error>(ev)) {
|
switch (static_cast<error>(ev)) {
|
||||||
case error::invalid_data_type: return "Invalid resp3 type.";
|
case error::invalid_data_type: return "Invalid resp3 type.";
|
||||||
case error::not_a_number: return "Can't convert string to number (maybe forgot to upgrade to RESP3?).";
|
case error::not_a_number:
|
||||||
case error::exceeeds_max_nested_depth: return "Exceeds the maximum number of nested responses.";
|
return "Can't convert string to number (maybe forgot to upgrade to RESP3?).";
|
||||||
|
case error::exceeeds_max_nested_depth:
|
||||||
|
return "Exceeds the maximum number of nested responses.";
|
||||||
case error::unexpected_bool_value: return "Unexpected bool value.";
|
case error::unexpected_bool_value: return "Unexpected bool value.";
|
||||||
case error::empty_field: return "Expected field value is empty.";
|
case error::empty_field: return "Expected field value is empty.";
|
||||||
case error::expects_resp3_simple_type: return "Expects a resp3 simple type.";
|
case error::expects_resp3_simple_type: return "Expects a resp3 simple type.";
|
||||||
@@ -42,7 +41,8 @@ struct error_category_impl : system::error_category {
|
|||||||
case error::connect_timeout: return "Connect timeout.";
|
case error::connect_timeout: return "Connect timeout.";
|
||||||
case error::pong_timeout: return "Pong timeout.";
|
case error::pong_timeout: return "Pong timeout.";
|
||||||
case error::ssl_handshake_timeout: return "SSL handshake timeout.";
|
case error::ssl_handshake_timeout: return "SSL handshake timeout.";
|
||||||
case error::sync_receive_push_failed: return "Can't receive server push synchronously without blocking.";
|
case error::sync_receive_push_failed:
|
||||||
|
return "Can't receive server push synchronously without blocking.";
|
||||||
case error::incompatible_node_depth: return "Incompatible node depth.";
|
case error::incompatible_node_depth: return "Incompatible node depth.";
|
||||||
case error::resp3_hello: return "RESP3 handshake error (hello command).";
|
case error::resp3_hello: return "RESP3 handshake error (hello command).";
|
||||||
default: BOOST_ASSERT(false); return "Boost.Redis error.";
|
default: BOOST_ASSERT(false); return "Boost.Redis error.";
|
||||||
@@ -56,11 +56,11 @@ auto category() -> system::error_category const&
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // detail
|
} // namespace detail
|
||||||
|
|
||||||
auto make_error_code(error e) -> system::error_code
|
auto make_error_code(error e) -> system::error_code
|
||||||
{
|
{
|
||||||
return system::error_code{static_cast<int>(e), detail::category()};
|
return system::error_code{static_cast<int>(e), detail::category()};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <boost/redis/ignore.hpp>
|
#include <boost/redis/ignore.hpp>
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
ignore_t ignore;
|
ignore_t ignore;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
void logger::write_prefix()
|
void logger::write_prefix()
|
||||||
{
|
{
|
||||||
@@ -18,7 +19,9 @@ void logger::write_prefix()
|
|||||||
std::clog << prefix_;
|
std::clog << prefix_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void logger::on_resolve(system::error_code const& ec, asio::ip::tcp::resolver::results_type const& res)
|
void logger::on_resolve(
|
||||||
|
system::error_code const& ec,
|
||||||
|
asio::ip::tcp::resolver::results_type const& res)
|
||||||
{
|
{
|
||||||
if (level_ < level::info)
|
if (level_ < level::info)
|
||||||
return;
|
return;
|
||||||
@@ -71,10 +74,7 @@ void logger::on_ssl_handshake(system::error_code const& ec)
|
|||||||
std::clog << "SSL handshake: " << ec.message() << std::endl;
|
std::clog << "SSL handshake: " << ec.message() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void logger::on_write(system::error_code const& ec, std::string_view payload)
|
||||||
logger::on_write(
|
|
||||||
system::error_code const& ec,
|
|
||||||
std::string_view payload)
|
|
||||||
{
|
{
|
||||||
if (level_ < level::info)
|
if (level_ < level::info)
|
||||||
return;
|
return;
|
||||||
@@ -104,10 +104,7 @@ void logger::on_read(system::error_code const& ec, std::size_t n)
|
|||||||
std::clog << std::endl;
|
std::clog << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void logger::on_hello(system::error_code const& ec, generic_response const& resp)
|
||||||
logger::on_hello(
|
|
||||||
system::error_code const& ec,
|
|
||||||
generic_response const& resp)
|
|
||||||
{
|
{
|
||||||
if (level_ < level::info)
|
if (level_ < level::info)
|
||||||
return;
|
return;
|
||||||
@@ -145,4 +142,4 @@ void logger::trace(std::string_view op, system::error_code const& ec)
|
|||||||
std::clog << op << ": " << ec.message() << std::endl;
|
std::clog << op << ": " << ec.message() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|||||||
@@ -9,8 +9,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace boost::redis::detail
|
namespace boost::redis::detail {
|
||||||
{
|
|
||||||
|
|
||||||
multiplexer::elem::elem(request const& req, pipeline_adapter_type adapter)
|
multiplexer::elem::elem(request const& req, pipeline_adapter_type adapter)
|
||||||
: req_{&req}
|
: req_{&req}
|
||||||
@@ -20,8 +19,7 @@ multiplexer::elem::elem(request const& req, pipeline_adapter_type adapter)
|
|||||||
, ec_{{}}
|
, ec_{{}}
|
||||||
, read_size_{0}
|
, read_size_{0}
|
||||||
{
|
{
|
||||||
adapter_ = [this, adapter](resp3::node_view const& nd, system::error_code& ec)
|
adapter_ = [this, adapter](resp3::node_view const& nd, system::error_code& ec) {
|
||||||
{
|
|
||||||
auto const i = req_->get_expected_responses() - remaining_responses_;
|
auto const i = req_->get_expected_responses() - remaining_responses_;
|
||||||
adapter(i, nd, ec);
|
adapter(i, nd, ec);
|
||||||
};
|
};
|
||||||
@@ -75,8 +73,7 @@ void multiplexer::add(std::shared_ptr<elem> const& info)
|
|||||||
reqs_.push_back(info);
|
reqs_.push_back(info);
|
||||||
|
|
||||||
if (info->get_request().has_hello_priority()) {
|
if (info->get_request().has_hello_priority()) {
|
||||||
auto rend =
|
auto rend = std::partition_point(std::rbegin(reqs_), std::rend(reqs_), [](auto const& e) {
|
||||||
std::partition_point(std::rbegin(reqs_), std::rend(reqs_), [](auto const& e) {
|
|
||||||
return e->is_waiting();
|
return e->is_waiting();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -84,8 +81,7 @@ void multiplexer::add(std::shared_ptr<elem> const& info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<tribool, std::size_t>
|
std::pair<tribool, std::size_t> multiplexer::commit_read(system::error_code& ec)
|
||||||
multiplexer::commit_read(system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
// We arrive here in two states:
|
// We arrive here in two states:
|
||||||
//
|
//
|
||||||
@@ -111,7 +107,9 @@ multiplexer::commit_read(system::error_code& ec)
|
|||||||
return std::make_pair(std::make_optional(true), size);
|
return std::make_pair(std::make_optional(true), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT_MSG(is_waiting_response(), "Not waiting for a response (using MONITOR command perhaps?)");
|
BOOST_ASSERT_MSG(
|
||||||
|
is_waiting_response(),
|
||||||
|
"Not waiting for a response (using MONITOR command perhaps?)");
|
||||||
BOOST_ASSERT(!reqs_.empty());
|
BOOST_ASSERT(!reqs_.empty());
|
||||||
BOOST_ASSERT(reqs_.front() != nullptr);
|
BOOST_ASSERT(reqs_.front() != nullptr);
|
||||||
BOOST_ASSERT(reqs_.front()->get_remaining_responses() != 0);
|
BOOST_ASSERT(reqs_.front()->get_remaining_responses() != 0);
|
||||||
@@ -148,8 +146,10 @@ std::size_t multiplexer::prepare_write()
|
|||||||
{
|
{
|
||||||
// Coalesces the requests and marks them staged. After a
|
// Coalesces the requests and marks them staged. After a
|
||||||
// successful write staged requests will be marked as written.
|
// successful write staged requests will be marked as written.
|
||||||
auto const point =
|
auto const point = std::partition_point(
|
||||||
std::partition_point(std::cbegin(reqs_), std::cend(reqs_), [](auto const& ri) {
|
std::cbegin(reqs_),
|
||||||
|
std::cend(reqs_),
|
||||||
|
[](auto const& ri) {
|
||||||
return !ri->is_waiting();
|
return !ri->is_waiting();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -166,11 +166,9 @@ std::size_t multiplexer::prepare_write()
|
|||||||
return static_cast<std::size_t>(d);
|
return static_cast<std::size_t>(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::size_t multiplexer::cancel_waiting()
|
std::size_t multiplexer::cancel_waiting()
|
||||||
{
|
{
|
||||||
auto f = [](auto const& ptr)
|
auto f = [](auto const& ptr) {
|
||||||
{
|
|
||||||
BOOST_ASSERT(ptr != nullptr);
|
BOOST_ASSERT(ptr != nullptr);
|
||||||
return !ptr->is_waiting();
|
return !ptr->is_waiting();
|
||||||
};
|
};
|
||||||
@@ -196,8 +194,7 @@ auto multiplexer::cancel_on_conn_lost() -> std::size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Must return false if the request should be removed.
|
// Must return false if the request should be removed.
|
||||||
auto cond = [](auto const& ptr)
|
auto cond = [](auto const& ptr) {
|
||||||
{
|
|
||||||
BOOST_ASSERT(ptr != nullptr);
|
BOOST_ASSERT(ptr != nullptr);
|
||||||
|
|
||||||
if (ptr->is_waiting()) {
|
if (ptr->is_waiting()) {
|
||||||
@@ -305,17 +302,12 @@ bool multiplexer::is_waiting_response() const noexcept
|
|||||||
return !reqs_.front()->is_waiting();
|
return !reqs_.front()->is_waiting();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool multiplexer::is_writing() const noexcept
|
bool multiplexer::is_writing() const noexcept { return !write_buffer_.empty(); }
|
||||||
{
|
|
||||||
return !write_buffer_.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto
|
auto make_elem(request const& req, multiplexer::pipeline_adapter_type adapter)
|
||||||
make_elem(
|
-> std::shared_ptr<multiplexer::elem>
|
||||||
request const& req,
|
|
||||||
multiplexer::pipeline_adapter_type adapter) -> std::shared_ptr<multiplexer::elem>
|
|
||||||
{
|
{
|
||||||
return std::make_shared<multiplexer::elem>(req, std::move(adapter));
|
return std::make_shared<multiplexer::elem>(req, std::move(adapter));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace boost::redis::detail
|
||||||
|
|||||||
@@ -12,10 +12,13 @@ namespace boost::redis::detail {
|
|||||||
|
|
||||||
auto has_response(std::string_view cmd) -> bool
|
auto has_response(std::string_view cmd) -> bool
|
||||||
{
|
{
|
||||||
if (cmd == "SUBSCRIBE") return true;
|
if (cmd == "SUBSCRIBE")
|
||||||
if (cmd == "PSUBSCRIBE") return true;
|
return true;
|
||||||
if (cmd == "UNSUBSCRIBE") return true;
|
if (cmd == "PSUBSCRIBE")
|
||||||
|
return true;
|
||||||
|
if (cmd == "UNSUBSCRIBE")
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost:redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
|
|
||||||
#include <boost/redis/detail/resp3_handshaker.hpp>
|
#include <boost/redis/detail/resp3_handshaker.hpp>
|
||||||
|
|
||||||
namespace boost::redis::detail
|
namespace boost::redis::detail {
|
||||||
{
|
|
||||||
|
|
||||||
void push_hello(config const& cfg, request& req)
|
void push_hello(config const& cfg, request& req)
|
||||||
{
|
{
|
||||||
@@ -24,4 +23,4 @@ void push_hello(config const& cfg, request& req)
|
|||||||
req.push("SELECT", cfg.database_index.value());
|
req.push("SELECT", cfg.database_index.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::detail
|
} // namespace boost::redis::detail
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/response.hpp>
|
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
void consume_one(generic_response& r, system::error_code& ec)
|
void consume_one(generic_response& r, system::error_code& ec)
|
||||||
{
|
{
|
||||||
@@ -29,8 +29,9 @@ void consume_one(generic_response& r, system::error_code& ec)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto f = [depth](auto const& e)
|
auto f = [depth](auto const& e) {
|
||||||
{ return e.depth == depth; };
|
return e.depth == depth;
|
||||||
|
};
|
||||||
|
|
||||||
auto match = std::find_if(std::next(std::cbegin(r.value())), std::cend(r.value()), f);
|
auto match = std::find_if(std::next(std::cbegin(r.value())), std::cend(r.value()), f);
|
||||||
|
|
||||||
@@ -45,4 +46,4 @@ void consume_one(generic_response& r)
|
|||||||
throw system::system_error(ec);
|
throw system::system_error(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis
|
||||||
|
|||||||
@@ -8,10 +8,14 @@
|
|||||||
#define BOOST_REDIS_LOGGER_HPP
|
#define BOOST_REDIS_LOGGER_HPP
|
||||||
|
|
||||||
#include <boost/redis/response.hpp>
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace boost::system {class error_code;}
|
namespace boost::system {
|
||||||
|
class error_code;
|
||||||
|
}
|
||||||
|
|
||||||
namespace boost::redis {
|
namespace boost::redis {
|
||||||
|
|
||||||
@@ -66,7 +70,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
logger(level l = level::debug)
|
logger(level l = level::debug)
|
||||||
: level_{l}
|
: level_{l}
|
||||||
{}
|
{ }
|
||||||
|
|
||||||
/** @brief Called when the resolve operation completes.
|
/** @brief Called when the resolve operation completes.
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -120,10 +124,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param prefix The prefix.
|
* @param prefix The prefix.
|
||||||
*/
|
*/
|
||||||
void set_prefix(std::string_view prefix)
|
void set_prefix(std::string_view prefix) { prefix_ = prefix; }
|
||||||
{
|
|
||||||
prefix_ = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void trace(std::string_view message);
|
void trace(std::string_view message);
|
||||||
void trace(std::string_view op, system::error_code const& ec);
|
void trace(std::string_view op, system::error_code const& ec);
|
||||||
@@ -134,6 +135,6 @@ private:
|
|||||||
std::string_view prefix_;
|
std::string_view prefix_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_LOGGER_HPP
|
#endif // BOOST_REDIS_LOGGER_HPP
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ namespace boost::redis {
|
|||||||
* The operations listed below can be passed to the
|
* The operations listed below can be passed to the
|
||||||
* `boost::redis::connection::cancel` member function.
|
* `boost::redis::connection::cancel` member function.
|
||||||
*/
|
*/
|
||||||
enum class operation {
|
enum class operation
|
||||||
|
{
|
||||||
/// Resolve operation.
|
/// Resolve operation.
|
||||||
resolve,
|
resolve,
|
||||||
/// Connect operation.
|
/// Connect operation.
|
||||||
@@ -36,6 +37,6 @@ enum class operation {
|
|||||||
all,
|
all,
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_OPERATION_HPP
|
#endif // BOOST_REDIS_OPERATION_HPP
|
||||||
|
|||||||
@@ -7,19 +7,19 @@
|
|||||||
#ifndef BOOST_REDIS_REQUEST_HPP
|
#ifndef BOOST_REDIS_REQUEST_HPP
|
||||||
#define BOOST_REDIS_REQUEST_HPP
|
#define BOOST_REDIS_REQUEST_HPP
|
||||||
|
|
||||||
#include <boost/redis/resp3/type.hpp>
|
|
||||||
#include <boost/redis/resp3/serialization.hpp>
|
#include <boost/redis/resp3/serialization.hpp>
|
||||||
|
#include <boost/redis/resp3/type.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
// NOTE: For some commands like hset it would be a good idea to assert
|
// NOTE: For some commands like hset it would be a good idea to assert
|
||||||
// the value type is a pair.
|
// the value type is a pair.
|
||||||
|
|
||||||
namespace boost::redis {
|
namespace boost::redis {
|
||||||
|
|
||||||
namespace detail{
|
namespace detail {
|
||||||
auto has_response(std::string_view cmd) -> bool;
|
auto has_response(std::string_view cmd) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,23 +80,25 @@ public:
|
|||||||
*
|
*
|
||||||
* \param cfg Configuration options.
|
* \param cfg Configuration options.
|
||||||
*/
|
*/
|
||||||
explicit
|
explicit request(config cfg = config{true, false, true, true})
|
||||||
request(config cfg = config{true, false, true, true})
|
: cfg_{cfg}
|
||||||
: cfg_{cfg} {}
|
{ }
|
||||||
|
|
||||||
//// Returns the number of responses expected for this request.
|
//// Returns the number of responses expected for this request.
|
||||||
[[nodiscard]] auto get_expected_responses() const noexcept -> std::size_t
|
[[nodiscard]] auto get_expected_responses() const noexcept -> std::size_t
|
||||||
{ return expected_responses_;};
|
{
|
||||||
|
return expected_responses_;
|
||||||
|
};
|
||||||
|
|
||||||
//// Returns the number of commands contained in this request.
|
//// Returns the number of commands contained in this request.
|
||||||
[[nodiscard]] auto get_commands() const noexcept -> std::size_t
|
[[nodiscard]] auto get_commands() const noexcept -> std::size_t { return commands_; };
|
||||||
{ return commands_;};
|
|
||||||
|
|
||||||
[[nodiscard]] auto payload() const noexcept -> std::string_view
|
[[nodiscard]] auto payload() const noexcept -> std::string_view { return payload_; }
|
||||||
{ return payload_;}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_hello_priority() const noexcept -> auto const&
|
[[nodiscard]] auto has_hello_priority() const noexcept -> auto const&
|
||||||
{ return has_hello_priority_;}
|
{
|
||||||
|
return has_hello_priority_;
|
||||||
|
}
|
||||||
|
|
||||||
/// Clears the request preserving allocated memory.
|
/// Clears the request preserving allocated memory.
|
||||||
void clear()
|
void clear()
|
||||||
@@ -108,14 +110,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls std::string::reserve on the internal storage.
|
/// Calls std::string::reserve on the internal storage.
|
||||||
void reserve(std::size_t new_cap = 0)
|
void reserve(std::size_t new_cap = 0) { payload_.reserve(new_cap); }
|
||||||
{ payload_.reserve(new_cap); }
|
|
||||||
|
|
||||||
/// Returns a const reference to the config object.
|
/// Returns a const reference to the config object.
|
||||||
[[nodiscard]] auto get_config() const noexcept -> auto const& {return cfg_; }
|
[[nodiscard]] auto get_config() const noexcept -> auto const& { return cfg_; }
|
||||||
|
|
||||||
/// Returns a reference to the config object.
|
/// Returns a reference to the config object.
|
||||||
[[nodiscard]] auto get_config() noexcept -> auto& {return cfg_; }
|
[[nodiscard]] auto get_config() noexcept -> auto& { return cfg_; }
|
||||||
|
|
||||||
/** @brief Appends a new command to the end of the request.
|
/** @brief Appends a new command to the end of the request.
|
||||||
*
|
*
|
||||||
@@ -185,13 +186,12 @@ public:
|
|||||||
* See cpp20_serialization.cpp
|
* See cpp20_serialization.cpp
|
||||||
*/
|
*/
|
||||||
template <class ForwardIterator>
|
template <class ForwardIterator>
|
||||||
void
|
void push_range(
|
||||||
push_range(
|
|
||||||
std::string_view const& cmd,
|
std::string_view const& cmd,
|
||||||
std::string_view const& key,
|
std::string_view const& key,
|
||||||
ForwardIterator begin,
|
ForwardIterator begin,
|
||||||
ForwardIterator end,
|
ForwardIterator end,
|
||||||
typename std::iterator_traits<ForwardIterator>::value_type * = nullptr)
|
typename std::iterator_traits<ForwardIterator>::value_type* = nullptr)
|
||||||
{
|
{
|
||||||
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
|
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
|
||||||
|
|
||||||
@@ -238,12 +238,11 @@ public:
|
|||||||
* See cpp20_serialization.cpp
|
* See cpp20_serialization.cpp
|
||||||
*/
|
*/
|
||||||
template <class ForwardIterator>
|
template <class ForwardIterator>
|
||||||
void
|
void push_range(
|
||||||
push_range(
|
|
||||||
std::string_view const& cmd,
|
std::string_view const& cmd,
|
||||||
ForwardIterator begin,
|
ForwardIterator begin,
|
||||||
ForwardIterator end,
|
ForwardIterator end,
|
||||||
typename std::iterator_traits<ForwardIterator>::value_type * = nullptr)
|
typename std::iterator_traits<ForwardIterator>::value_type* = nullptr)
|
||||||
{
|
{
|
||||||
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
|
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
|
||||||
|
|
||||||
@@ -272,12 +271,11 @@ public:
|
|||||||
* \tparam A type that can be passed to `std::cbegin()` and `std::cend()`.
|
* \tparam A type that can be passed to `std::cbegin()` and `std::cend()`.
|
||||||
*/
|
*/
|
||||||
template <class Range>
|
template <class Range>
|
||||||
void
|
void push_range(
|
||||||
push_range(
|
|
||||||
std::string_view const& cmd,
|
std::string_view const& cmd,
|
||||||
std::string_view const& key,
|
std::string_view const& key,
|
||||||
Range const& range,
|
Range const& range,
|
||||||
decltype(std::begin(range)) * = nullptr)
|
decltype(std::begin(range))* = nullptr)
|
||||||
{
|
{
|
||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
@@ -294,11 +292,10 @@ public:
|
|||||||
* \tparam A type that can be passed to `std::cbegin()` and `std::cend()`.
|
* \tparam A type that can be passed to `std::cbegin()` and `std::cend()`.
|
||||||
*/
|
*/
|
||||||
template <class Range>
|
template <class Range>
|
||||||
void
|
void push_range(
|
||||||
push_range(
|
|
||||||
std::string_view cmd,
|
std::string_view cmd,
|
||||||
Range const& range,
|
Range const& range,
|
||||||
decltype(std::cbegin(range)) * = nullptr)
|
decltype(std::cbegin(range))* = nullptr)
|
||||||
{
|
{
|
||||||
using std::cbegin;
|
using std::cbegin;
|
||||||
using std::cend;
|
using std::cend;
|
||||||
@@ -324,6 +321,6 @@ private:
|
|||||||
bool has_hello_priority_ = false;
|
bool has_hello_priority_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_REQUEST_HPP
|
#endif // BOOST_REDIS_REQUEST_HPP
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/resp3/parser.hpp>
|
|
||||||
#include <boost/redis/error.hpp>
|
#include <boost/redis/error.hpp>
|
||||||
|
#include <boost/redis/resp3/parser.hpp>
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
@@ -20,10 +21,7 @@ void to_int(std::size_t& i, std::string_view sv, system::error_code& ec)
|
|||||||
ec = error::not_a_number;
|
ec = error::not_a_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser::parser()
|
parser::parser() { reset(); }
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void parser::reset()
|
void parser::reset()
|
||||||
{
|
{
|
||||||
@@ -35,8 +33,7 @@ void parser::reset()
|
|||||||
sizes_[0] = 2; // The sentinel must be more than 1.
|
sizes_[0] = 2; // The sentinel must be more than 1.
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
std::size_t parser::get_suggested_buffer_growth(std::size_t hint) const noexcept
|
||||||
parser::get_suggested_buffer_growth(std::size_t hint) const noexcept
|
|
||||||
{
|
{
|
||||||
if (!bulk_expected())
|
if (!bulk_expected())
|
||||||
return hint;
|
return hint;
|
||||||
@@ -47,20 +44,14 @@ parser::get_suggested_buffer_growth(std::size_t hint) const noexcept
|
|||||||
return hint;
|
return hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t
|
std::size_t parser::get_consumed() const noexcept { return consumed_; }
|
||||||
parser::get_consumed() const noexcept
|
|
||||||
{
|
|
||||||
return consumed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool parser::done() const noexcept
|
||||||
parser::done() const noexcept
|
|
||||||
{
|
{
|
||||||
return depth_ == 0 && bulk_ == type::invalid && consumed_ != 0;
|
return depth_ == 0 && bulk_ == type::invalid && consumed_ != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void parser::commit_elem() noexcept
|
||||||
parser::commit_elem() noexcept
|
|
||||||
{
|
{
|
||||||
--sizes_[depth_];
|
--sizes_[depth_];
|
||||||
while (sizes_[depth_] == 0) {
|
while (sizes_[depth_] == 0) {
|
||||||
@@ -69,8 +60,7 @@ parser::commit_elem() noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto
|
auto parser::consume(std::string_view view, system::error_code& ec) noexcept -> parser::result
|
||||||
parser::consume(std::string_view view, system::error_code& ec) noexcept -> parser::result
|
|
||||||
{
|
{
|
||||||
switch (bulk_) {
|
switch (bulk_) {
|
||||||
case type::invalid:
|
case type::invalid:
|
||||||
@@ -88,8 +78,8 @@ parser::consume(std::string_view view, system::error_code& ec) noexcept -> parse
|
|||||||
consumed_ = pos + 2;
|
consumed_ = pos + 2;
|
||||||
if (!bulk_expected())
|
if (!bulk_expected())
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
} [[fallthrough]];
|
[[fallthrough]];
|
||||||
|
|
||||||
default: // Handles bulk.
|
default: // Handles bulk.
|
||||||
{
|
{
|
||||||
@@ -108,11 +98,8 @@ parser::consume(std::string_view view, system::error_code& ec) noexcept -> parse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto
|
auto parser::consume_impl(type t, std::string_view elem, system::error_code& ec)
|
||||||
parser::consume_impl(
|
-> parser::node_type
|
||||||
type t,
|
|
||||||
std::string_view elem,
|
|
||||||
system::error_code& ec) -> parser::node_type
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!bulk_expected());
|
BOOST_ASSERT(!bulk_expected());
|
||||||
|
|
||||||
@@ -120,7 +107,7 @@ parser::consume_impl(
|
|||||||
switch (t) {
|
switch (t) {
|
||||||
case type::streamed_string_part:
|
case type::streamed_string_part:
|
||||||
{
|
{
|
||||||
to_int(bulk_length_ , elem, ec);
|
to_int(bulk_length_, elem, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@@ -145,7 +132,7 @@ parser::consume_impl(
|
|||||||
sizes_[++depth_] = (std::numeric_limits<std::size_t>::max)();
|
sizes_[++depth_] = (std::numeric_limits<std::size_t>::max)();
|
||||||
ret = {type::streamed_string, 0, depth_, {}};
|
ret = {type::streamed_string, 0, depth_, {}};
|
||||||
} else {
|
} else {
|
||||||
to_int(bulk_length_ , elem , ec);
|
to_int(bulk_length_, elem, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@@ -175,7 +162,8 @@ parser::consume_impl(
|
|||||||
ec = error::empty_field;
|
ec = error::empty_field;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
} [[fallthrough]];
|
}
|
||||||
|
[[fallthrough]];
|
||||||
case type::simple_error:
|
case type::simple_error:
|
||||||
case type::simple_string:
|
case type::simple_string:
|
||||||
case type::null:
|
case type::null:
|
||||||
@@ -217,4 +205,4 @@ parser::consume_impl(
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis::resp3
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/resp3/serialization.hpp>
|
|
||||||
#include <boost/redis/resp3/parser.hpp>
|
#include <boost/redis/resp3/parser.hpp>
|
||||||
|
#include <boost/redis/resp3/serialization.hpp>
|
||||||
|
|
||||||
namespace boost::redis::resp3 {
|
namespace boost::redis::resp3 {
|
||||||
|
|
||||||
@@ -35,8 +35,5 @@ void add_blob(std::string& payload, std::string_view blob)
|
|||||||
payload += parser::sep;
|
payload += parser::sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_separator(std::string& payload)
|
void add_separator(std::string& payload) { payload += parser::sep; }
|
||||||
{
|
} // namespace boost::redis::resp3
|
||||||
payload += parser::sep;
|
|
||||||
}
|
|
||||||
} // boost::redis::resp3
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/resp3/type.hpp>
|
#include <boost/redis/resp3/type.hpp>
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
namespace boost::redis::resp3 {
|
namespace boost::redis::resp3 {
|
||||||
@@ -39,4 +40,4 @@ auto operator<<(std::ostream& os, type t) -> std::ostream&
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis::resp3
|
||||||
|
|||||||
@@ -48,10 +48,12 @@ struct basic_node {
|
|||||||
template <class String>
|
template <class String>
|
||||||
auto operator==(basic_node<String> const& a, basic_node<String> const& b)
|
auto operator==(basic_node<String> const& a, basic_node<String> const& b)
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
return a.aggregate_size == b.aggregate_size
|
return a.aggregate_size == b.aggregate_size
|
||||||
&& a.depth == b.depth
|
&& a.depth == b.depth
|
||||||
&& a.data_type == b.data_type
|
&& a.data_type == b.data_type
|
||||||
&& a.value == b.value;
|
&& a.value == b.value;
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief A node in the response tree that owns its data
|
/** @brief A node in the response tree that owns its data
|
||||||
@@ -64,6 +66,6 @@ using node = basic_node<std::string>;
|
|||||||
*/
|
*/
|
||||||
using node_view = basic_node<std::string_view>;
|
using node_view = basic_node<std::string_view>;
|
||||||
|
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis::resp3
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RESP3_NODE_HPP
|
#endif // BOOST_REDIS_RESP3_NODE_HPP
|
||||||
|
|||||||
@@ -8,11 +8,13 @@
|
|||||||
#define BOOST_REDIS_RESP3_PARSER_HPP
|
#define BOOST_REDIS_RESP3_PARSER_HPP
|
||||||
|
|
||||||
#include <boost/redis/resp3/node.hpp>
|
#include <boost/redis/resp3/node.hpp>
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <string_view>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace boost::redis::resp3 {
|
namespace boost::redis::resp3 {
|
||||||
|
|
||||||
@@ -54,7 +56,9 @@ private:
|
|||||||
// returns type::invalid.
|
// returns type::invalid.
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto bulk_expected() const noexcept -> bool
|
auto bulk_expected() const noexcept -> bool
|
||||||
{ return bulk_ != type::invalid; }
|
{
|
||||||
|
return bulk_ != type::invalid;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
parser();
|
parser();
|
||||||
@@ -76,12 +80,7 @@ public:
|
|||||||
// parser is either done or an error occured, that can be checked on
|
// parser is either done or an error occured, that can be checked on
|
||||||
// ec.
|
// ec.
|
||||||
template <class Adapter>
|
template <class Adapter>
|
||||||
bool
|
bool parse(resp3::parser& p, std::string_view const& msg, Adapter& adapter, system::error_code& ec)
|
||||||
parse(
|
|
||||||
resp3::parser& p,
|
|
||||||
std::string_view const& msg,
|
|
||||||
Adapter& adapter,
|
|
||||||
system::error_code& ec)
|
|
||||||
{
|
{
|
||||||
while (!p.done()) {
|
while (!p.done()) {
|
||||||
auto const res = p.consume(msg, ec);
|
auto const res = p.consume(msg, ec);
|
||||||
@@ -99,6 +98,6 @@ parse(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis::resp3
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RESP3_PARSER_HPP
|
#endif // BOOST_REDIS_RESP3_PARSER_HPP
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
#ifndef BOOST_REDIS_RESP3_SERIALIZATION_HPP
|
#ifndef BOOST_REDIS_RESP3_SERIALIZATION_HPP
|
||||||
#define BOOST_REDIS_RESP3_SERIALIZATION_HPP
|
#define BOOST_REDIS_RESP3_SERIALIZATION_HPP
|
||||||
|
|
||||||
|
#include <boost/redis/resp3/parser.hpp>
|
||||||
#include <boost/redis/resp3/type.hpp>
|
#include <boost/redis/resp3/type.hpp>
|
||||||
|
|
||||||
#include <boost/system/system_error.hpp>
|
#include <boost/system/system_error.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <boost/redis/resp3/parser.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
@@ -57,12 +58,11 @@ struct add_bulk_impl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ...Ts>
|
template <class... Ts>
|
||||||
struct add_bulk_impl<std::tuple<Ts...>> {
|
struct add_bulk_impl<std::tuple<Ts...>> {
|
||||||
static void add(std::string& payload, std::tuple<Ts...> const& t)
|
static void add(std::string& payload, std::tuple<Ts...> const& t)
|
||||||
{
|
{
|
||||||
auto f = [&](auto const&... vs)
|
auto f = [&](auto const&... vs) {
|
||||||
{
|
|
||||||
using namespace boost::redis::resp3;
|
using namespace boost::redis::resp3;
|
||||||
(boost_redis_to_bulk(payload, vs), ...);
|
(boost_redis_to_bulk(payload, vs), ...);
|
||||||
};
|
};
|
||||||
@@ -105,8 +105,7 @@ struct bulk_counter<std::pair<T, U>> {
|
|||||||
void add_blob(std::string& payload, std::string_view blob);
|
void add_blob(std::string& payload, std::string_view blob);
|
||||||
void add_separator(std::string& payload);
|
void add_separator(std::string& payload);
|
||||||
|
|
||||||
namespace detail
|
namespace detail {
|
||||||
{
|
|
||||||
|
|
||||||
template <class Adapter>
|
template <class Adapter>
|
||||||
void deserialize(std::string_view const& data, Adapter adapter, system::error_code& ec)
|
void deserialize(std::string_view const& data, Adapter adapter, system::error_code& ec)
|
||||||
@@ -137,8 +136,8 @@ void deserialize(std::string_view const& data, Adapter adapter)
|
|||||||
BOOST_THROW_EXCEPTION(system::system_error{ec});
|
BOOST_THROW_EXCEPTION(system::system_error{ec});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace detail
|
||||||
|
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis::resp3
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RESP3_SERIALIZATION_HPP
|
#endif // BOOST_REDIS_RESP3_SERIALIZATION_HPP
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
#define BOOST_REDIS_RESP3_TYPE_HPP
|
#define BOOST_REDIS_RESP3_TYPE_HPP
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace boost::redis::resp3 {
|
namespace boost::redis::resp3 {
|
||||||
|
|
||||||
@@ -145,6 +146,6 @@ constexpr auto to_type(char c) noexcept -> type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // boost::redis::resp3
|
} // namespace boost::redis::resp3
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RESP3_TYPE_HPP
|
#endif // BOOST_REDIS_RESP3_TYPE_HPP
|
||||||
|
|||||||
@@ -7,16 +7,16 @@
|
|||||||
#ifndef BOOST_REDIS_RESPONSE_HPP
|
#ifndef BOOST_REDIS_RESPONSE_HPP
|
||||||
#define BOOST_REDIS_RESPONSE_HPP
|
#define BOOST_REDIS_RESPONSE_HPP
|
||||||
|
|
||||||
#include <boost/redis/resp3/node.hpp>
|
|
||||||
#include <boost/redis/adapter/result.hpp>
|
#include <boost/redis/adapter/result.hpp>
|
||||||
|
#include <boost/redis/resp3/node.hpp>
|
||||||
|
|
||||||
#include <boost/system.hpp>
|
#include <boost/system.hpp>
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
/** @brief Response with compile-time size.
|
/** @brief Response with compile-time size.
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -75,6 +75,6 @@ void consume_one(generic_response& r, system::error_code& ec);
|
|||||||
/// Throwing overload of `consume_one`.
|
/// Throwing overload of `consume_one`.
|
||||||
void consume_one(generic_response& r);
|
void consume_one(generic_response& r);
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_RESPONSE_HPP
|
#endif // BOOST_REDIS_RESPONSE_HPP
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/impl/error.ipp>
|
|
||||||
#include <boost/redis/impl/logger.ipp>
|
|
||||||
#include <boost/redis/impl/request.ipp>
|
|
||||||
#include <boost/redis/impl/ignore.ipp>
|
|
||||||
#include <boost/redis/impl/connection.ipp>
|
#include <boost/redis/impl/connection.ipp>
|
||||||
#include <boost/redis/impl/response.ipp>
|
#include <boost/redis/impl/error.ipp>
|
||||||
#include <boost/redis/impl/resp3_handshaker.ipp>
|
#include <boost/redis/impl/ignore.ipp>
|
||||||
|
#include <boost/redis/impl/logger.ipp>
|
||||||
#include <boost/redis/impl/multiplexer.ipp>
|
#include <boost/redis/impl/multiplexer.ipp>
|
||||||
#include <boost/redis/resp3/impl/type.ipp>
|
#include <boost/redis/impl/request.ipp>
|
||||||
|
#include <boost/redis/impl/resp3_handshaker.ipp>
|
||||||
|
#include <boost/redis/impl/response.ipp>
|
||||||
#include <boost/redis/resp3/impl/parser.ipp>
|
#include <boost/redis/resp3/impl/parser.ipp>
|
||||||
#include <boost/redis/resp3/impl/serialization.ipp>
|
#include <boost/redis/resp3/impl/serialization.ipp>
|
||||||
|
#include <boost/redis/resp3/impl/type.ipp>
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
#ifndef BOOST_REDIS_USAGE_HPP
|
#ifndef BOOST_REDIS_USAGE_HPP
|
||||||
#define BOOST_REDIS_USAGE_HPP
|
#define BOOST_REDIS_USAGE_HPP
|
||||||
|
|
||||||
namespace boost::redis
|
namespace boost::redis {
|
||||||
{
|
|
||||||
|
|
||||||
/** @brief Connection usage information.
|
/** @brief Connection usage information.
|
||||||
* @ingroup high-level-api
|
* @ingroup high-level-api
|
||||||
@@ -38,6 +37,6 @@ struct usage {
|
|||||||
std::size_t push_bytes_received = 0;
|
std::size_t push_bytes_received = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // boost::redis
|
} // namespace boost::redis
|
||||||
|
|
||||||
#endif // BOOST_REDIS_USAGE_HPP
|
#endif // BOOST_REDIS_USAGE_HPP
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/src.hpp>
|
#include <boost/redis/src.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/src.hpp>
|
#include <boost/redis/src.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/src.hpp>
|
#include <boost/redis/src.hpp>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include "common.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <boost/asio/consign.hpp>
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
|
#include <boost/asio/consign.hpp>
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
|
|
||||||
@@ -18,8 +20,7 @@ struct run_callback {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void run(
|
||||||
run(
|
|
||||||
std::shared_ptr<boost::redis::connection> conn,
|
std::shared_ptr<boost::redis::connection> conn,
|
||||||
boost::redis::config cfg,
|
boost::redis::config cfg,
|
||||||
boost::system::error_code ec,
|
boost::system::error_code ec,
|
||||||
@@ -43,10 +44,7 @@ static std::string safe_getenv(const char* name, const char* default_value)
|
|||||||
return res ? res : default_value;
|
return res ? res : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_server_hostname()
|
std::string get_server_hostname() { return safe_getenv("BOOST_REDIS_TEST_SERVER", "localhost"); }
|
||||||
{
|
|
||||||
return safe_getenv("BOOST_REDIS_TEST_SERVER", "localhost");
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::redis::config make_test_config()
|
boost::redis::config make_test_config()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/system/error_code.hpp>
|
|
||||||
#include <boost/asio/redirect_error.hpp>
|
|
||||||
#include <boost/asio/awaitable.hpp>
|
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/operation.hpp>
|
#include <boost/redis/operation.hpp>
|
||||||
|
|
||||||
|
#include <boost/asio/awaitable.hpp>
|
||||||
|
#include <boost/asio/redirect_error.hpp>
|
||||||
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
|
#include <boost/system/error_code.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
||||||
inline
|
inline auto redir(boost::system::error_code& ec)
|
||||||
auto redir(boost::system::error_code& ec)
|
{
|
||||||
{ return boost::asio::redirect_error(boost::asio::use_awaitable, ec); }
|
return boost::asio::redirect_error(boost::asio::use_awaitable, ec);
|
||||||
|
}
|
||||||
auto start(boost::asio::awaitable<void> op) -> int;
|
auto start(boost::asio::awaitable<void> op) -> int;
|
||||||
#endif // BOOST_ASIO_HAS_CO_AWAIT
|
#endif // BOOST_ASIO_HAS_CO_AWAIT
|
||||||
|
|
||||||
boost::redis::config make_test_config();
|
boost::redis::config make_test_config();
|
||||||
std::string get_server_hostname();
|
std::string get_server_hostname();
|
||||||
|
|
||||||
void
|
void run(
|
||||||
run(
|
|
||||||
std::shared_ptr<boost::redis::connection> conn,
|
std::shared_ptr<boost::redis::connection> conn,
|
||||||
boost::redis::config cfg = make_test_config(),
|
boost::redis::config cfg = make_test_config(),
|
||||||
boost::system::error_code ec = boost::asio::error::operation_aborted,
|
boost::system::error_code ec = boost::asio::error::operation_aborted,
|
||||||
boost::redis::operation op = boost::redis::operation::receive,
|
boost::redis::operation op = boost::redis::operation::receive,
|
||||||
boost::redis::logger::level l = boost::redis::logger::level::debug);
|
boost::redis::logger::level l = boost::redis::logger::level::debug);
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <boost/redis/adapter/any_adapter.hpp>
|
||||||
#include <boost/redis/ignore.hpp>
|
#include <boost/redis/ignore.hpp>
|
||||||
#include <boost/redis/response.hpp>
|
#include <boost/redis/response.hpp>
|
||||||
#include <boost/redis/adapter/any_adapter.hpp>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#define BOOST_TEST_MODULE any_adapter
|
#define BOOST_TEST_MODULE any_adapter
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
@@ -33,13 +34,13 @@ BOOST_AUTO_TEST_CASE(any_adapter_copy_move)
|
|||||||
{
|
{
|
||||||
// any_adapter can be copied/moved
|
// any_adapter can be copied/moved
|
||||||
response<int, std::string> r;
|
response<int, std::string> r;
|
||||||
any_adapter ad1 {r};
|
any_adapter ad1{r};
|
||||||
|
|
||||||
// copy constructor
|
// copy constructor
|
||||||
any_adapter ad2 {ad1};
|
any_adapter ad2{ad1};
|
||||||
|
|
||||||
// move constructor
|
// move constructor
|
||||||
any_adapter ad3 {std::move(ad2)};
|
any_adapter ad3{std::move(ad2)};
|
||||||
|
|
||||||
// copy assignment
|
// copy assignment
|
||||||
BOOST_CHECK_NO_THROW(ad2 = ad1);
|
BOOST_CHECK_NO_THROW(ad2 = ad1);
|
||||||
|
|||||||
@@ -6,12 +6,15 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/response.hpp>
|
#include <boost/redis/response.hpp>
|
||||||
|
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
#define BOOST_TEST_MODULE check-health
|
#define BOOST_TEST_MODULE check_health
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "common.hpp"
|
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
namespace redis = boost::redis;
|
namespace redis = boost::redis;
|
||||||
@@ -35,7 +38,7 @@ struct push_callback {
|
|||||||
|
|
||||||
void operator()(error_code ec = {}, std::size_t = 0)
|
void operator()(error_code ec = {}, std::size_t = 0)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_REENTER (coro) for (;;)
|
BOOST_ASIO_CORO_REENTER(coro) for (;;)
|
||||||
{
|
{
|
||||||
BOOST_ASIO_CORO_YIELD
|
BOOST_ASIO_CORO_YIELD
|
||||||
conn2->async_receive(*this);
|
conn2->async_receive(*this);
|
||||||
@@ -94,7 +97,7 @@ BOOST_AUTO_TEST_CASE(check_health)
|
|||||||
auto cfg2 = make_test_config();
|
auto cfg2 = make_test_config();
|
||||||
cfg2.health_check_id = "conn2";
|
cfg2.health_check_id = "conn2";
|
||||||
error_code res2;
|
error_code res2;
|
||||||
conn2.async_run(cfg2, {}, [&](auto ec){
|
conn2.async_run(cfg2, {}, [&](auto ec) {
|
||||||
std::cout << "async_run 2 completed: " << ec.message() << std::endl;
|
std::cout << "async_run 2 completed: " << ec.message() << std::endl;
|
||||||
res2 = ec;
|
res2 = ec;
|
||||||
});
|
});
|
||||||
@@ -122,4 +125,3 @@ BOOST_AUTO_TEST_CASE(check_health)
|
|||||||
// to fail.
|
// to fail.
|
||||||
std::this_thread::sleep_for(std::chrono::seconds{10});
|
std::this_thread::sleep_for(std::chrono::seconds{10});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/deferred.hpp>
|
#include <boost/asio/deferred.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
#define BOOST_TEST_MODULE echo-stress
|
#define BOOST_TEST_MODULE echo_stress
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
@@ -30,8 +33,7 @@ using boost::redis::error;
|
|||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, usage const& u)
|
std::ostream& operator<<(std::ostream& os, usage const& u)
|
||||||
{
|
{
|
||||||
os
|
os << "Commands sent: " << u.commands_sent << "\n"
|
||||||
<< "Commands sent: " << u.commands_sent << "\n"
|
|
||||||
<< "Bytes sent: " << u.bytes_sent << "\n"
|
<< "Bytes sent: " << u.bytes_sent << "\n"
|
||||||
<< "Responses received: " << u.responses_received << "\n"
|
<< "Responses received: " << u.responses_received << "\n"
|
||||||
<< "Pushes received: " << u.pushes_received << "\n"
|
<< "Pushes received: " << u.pushes_received << "\n"
|
||||||
@@ -65,11 +67,8 @@ auto push_consumer(std::shared_ptr<connection> conn, int expected) -> net::await
|
|||||||
conn->cancel();
|
conn->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto
|
auto echo_session(std::shared_ptr<connection> conn, std::shared_ptr<request> pubs, int n)
|
||||||
echo_session(
|
-> net::awaitable<void>
|
||||||
std::shared_ptr<connection> conn,
|
|
||||||
std::shared_ptr<request> pubs,
|
|
||||||
int n) -> net::awaitable<void>
|
|
||||||
{
|
{
|
||||||
for (auto i = 0; i < n; ++i)
|
for (auto i = 0; i < n; ++i)
|
||||||
co_await conn->async_exec(*pubs, ignore, net::deferred);
|
co_await conn->async_exec(*pubs, ignore, net::deferred);
|
||||||
@@ -80,7 +79,9 @@ auto async_echo_stress(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
|||||||
auto ex = co_await net::this_coro::executor;
|
auto ex = co_await net::this_coro::executor;
|
||||||
auto cfg = make_test_config();
|
auto cfg = make_test_config();
|
||||||
cfg.health_check_interval = std::chrono::seconds::zero();
|
cfg.health_check_interval = std::chrono::seconds::zero();
|
||||||
run(conn, cfg,
|
run(
|
||||||
|
conn,
|
||||||
|
cfg,
|
||||||
boost::asio::error::operation_aborted,
|
boost::asio::error::operation_aborted,
|
||||||
boost::redis::operation::receive,
|
boost::redis::operation::receive,
|
||||||
boost::redis::logger::level::crit);
|
boost::redis::logger::level::crit);
|
||||||
@@ -123,15 +124,9 @@ BOOST_AUTO_TEST_CASE(echo_stress)
|
|||||||
net::co_spawn(ioc, async_echo_stress(conn), net::detached);
|
net::co_spawn(ioc, async_echo_stress(conn), net::detached);
|
||||||
ioc.run();
|
ioc.run();
|
||||||
|
|
||||||
std::cout
|
std::cout << "-------------------\n" << conn->get_usage() << std::endl;
|
||||||
<< "-------------------\n"
|
|
||||||
<< conn->get_usage()
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
BOOST_AUTO_TEST_CASE(dummy)
|
BOOST_AUTO_TEST_CASE(dummy) { BOOST_TEST(true); }
|
||||||
{
|
|
||||||
BOOST_TEST(true);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,14 +6,18 @@
|
|||||||
|
|
||||||
#include <boost/redis/adapter/any_adapter.hpp>
|
#include <boost/redis/adapter/any_adapter.hpp>
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/system/errc.hpp>
|
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/system/errc.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#define BOOST_TEST_MODULE conn-exec
|
#define BOOST_TEST_MODULE conn_exec
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
// TODO: Test whether HELLO won't be inserted passt commands that have
|
// TODO: Test whether HELLO won't be inserted passt commands that have
|
||||||
// been already writen.
|
// been already writen.
|
||||||
// TODO: Test async_exec with empty request e.g. hgetall with an empty
|
// TODO: Test async_exec with empty request e.g. hgetall with an empty
|
||||||
@@ -53,7 +57,7 @@ BOOST_AUTO_TEST_CASE(hello_priority)
|
|||||||
bool seen2 = false;
|
bool seen2 = false;
|
||||||
bool seen3 = false;
|
bool seen3 = false;
|
||||||
|
|
||||||
conn->async_exec(req1, ignore, [&](auto ec, auto){
|
conn->async_exec(req1, ignore, [&](auto ec, auto) {
|
||||||
// Second callback to the called.
|
// Second callback to the called.
|
||||||
std::cout << "req1" << std::endl;
|
std::cout << "req1" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
@@ -62,7 +66,7 @@ BOOST_AUTO_TEST_CASE(hello_priority)
|
|||||||
seen1 = true;
|
seen1 = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
conn->async_exec(req2, ignore, [&](auto ec, auto){
|
conn->async_exec(req2, ignore, [&](auto ec, auto) {
|
||||||
// Last callback to the called.
|
// Last callback to the called.
|
||||||
std::cout << "req2" << std::endl;
|
std::cout << "req2" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
@@ -73,7 +77,7 @@ BOOST_AUTO_TEST_CASE(hello_priority)
|
|||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
});
|
});
|
||||||
|
|
||||||
conn->async_exec(req3, ignore, [&](auto ec, auto){
|
conn->async_exec(req3, ignore, [&](auto ec, auto) {
|
||||||
// Callback that will be called first.
|
// Callback that will be called first.
|
||||||
std::cout << "req3" << std::endl;
|
std::cout << "req3" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
@@ -98,7 +102,7 @@ BOOST_AUTO_TEST_CASE(wrong_response_data_type)
|
|||||||
|
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
conn->async_exec(req, resp, [conn](auto ec, auto){
|
conn->async_exec(req, resp, [conn](auto ec, auto) {
|
||||||
BOOST_CHECK_EQUAL(ec, boost::redis::error::not_a_number);
|
BOOST_CHECK_EQUAL(ec, boost::redis::error::not_a_number);
|
||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
});
|
});
|
||||||
@@ -115,7 +119,7 @@ BOOST_AUTO_TEST_CASE(cancel_request_if_not_connected)
|
|||||||
|
|
||||||
net::io_context ioc;
|
net::io_context ioc;
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
conn->async_exec(req, ignore, [conn](auto ec, auto){
|
conn->async_exec(req, ignore, [conn](auto ec, auto) {
|
||||||
BOOST_CHECK_EQUAL(ec, boost::redis::error::not_connected);
|
BOOST_CHECK_EQUAL(ec, boost::redis::error::not_connected);
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
});
|
});
|
||||||
@@ -137,13 +141,13 @@ BOOST_AUTO_TEST_CASE(correct_database)
|
|||||||
|
|
||||||
generic_response resp;
|
generic_response resp;
|
||||||
|
|
||||||
conn->async_exec(req, resp, [&](auto ec, auto n){
|
conn->async_exec(req, resp, [&](auto ec, auto n) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
std::clog << "async_exec has completed: " << n << std::endl;
|
std::clog << "async_exec has completed: " << n << std::endl;
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
conn->async_run(cfg, {}, [](auto){
|
conn->async_run(cfg, {}, [](auto) {
|
||||||
std::clog << "async_run has exited." << std::endl;
|
std::clog << "async_run has exited." << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -204,7 +208,7 @@ BOOST_AUTO_TEST_CASE(exec_any_adapter)
|
|||||||
|
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
conn->async_exec(req, boost::redis::any_adapter(res), [&](auto ec, auto){
|
conn->async_exec(req, boost::redis::any_adapter(res), [&](auto ec, auto) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
});
|
});
|
||||||
@@ -214,4 +218,3 @@ BOOST_AUTO_TEST_CASE(exec_any_adapter)
|
|||||||
|
|
||||||
BOOST_TEST(std::get<0>(res).value() == "PONG");
|
BOOST_TEST(std::get<0>(res).value() == "PONG");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-exec-cancel
|
#define BOOST_TEST_MODULE conn_exec_cancel
|
||||||
#include <boost/test/included/unit_test.hpp>
|
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
||||||
@@ -57,10 +60,7 @@ auto implicit_cancel_of_req_written() -> net::awaitable<void>
|
|||||||
|
|
||||||
// Achieves implicit cancellation when the timer fires.
|
// Achieves implicit cancellation when the timer fires.
|
||||||
boost::system::error_code ec1, ec2;
|
boost::system::error_code ec1, ec2;
|
||||||
co_await (
|
co_await (conn->async_exec(req1, ignore, redir(ec1)) || st.async_wait(redir(ec2)));
|
||||||
conn->async_exec(req1, ignore, redir(ec1)) ||
|
|
||||||
st.async_wait(redir(ec2))
|
|
||||||
);
|
|
||||||
|
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
|
|
||||||
@@ -92,13 +92,11 @@ BOOST_AUTO_TEST_CASE(test_cancel_of_req_written_on_run_canceled)
|
|||||||
req1.get_config().cancel_if_unresponded = true;
|
req1.get_config().cancel_if_unresponded = true;
|
||||||
req1.push("BLPOP", "any", 0);
|
req1.push("BLPOP", "any", 0);
|
||||||
|
|
||||||
auto c1 = [&](auto ec, auto)
|
auto c1 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
BOOST_CHECK_EQUAL(ec, net::error::operation_aborted);
|
BOOST_CHECK_EQUAL(ec, net::error::operation_aborted);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c0 = [&](auto ec, auto)
|
auto c0 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req1, ignore, c1);
|
conn->async_exec(req1, ignore, c1);
|
||||||
};
|
};
|
||||||
@@ -111,7 +109,7 @@ BOOST_AUTO_TEST_CASE(test_cancel_of_req_written_on_run_canceled)
|
|||||||
|
|
||||||
net::steady_timer st{ioc};
|
net::steady_timer st{ioc};
|
||||||
st.expires_after(std::chrono::seconds{1});
|
st.expires_after(std::chrono::seconds{1});
|
||||||
st.async_wait([&](auto ec){
|
st.async_wait([&](auto ec) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->cancel(operation::run);
|
conn->cancel(operation::run);
|
||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
@@ -121,8 +119,5 @@ BOOST_AUTO_TEST_CASE(test_cancel_of_req_written_on_run_canceled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
BOOST_AUTO_TEST_CASE(dummy)
|
BOOST_AUTO_TEST_CASE(dummy) { BOOST_TEST(true); }
|
||||||
{
|
|
||||||
BOOST_TEST(true);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-exec-cancel
|
#define BOOST_TEST_MODULE conn_exec_cancel
|
||||||
#include <boost/test/included/unit_test.hpp>
|
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
||||||
@@ -55,7 +58,7 @@ auto async_ignore_explicit_cancel_of_req_written() -> net::awaitable<void>
|
|||||||
req1.push("BLPOP", "any", 3);
|
req1.push("BLPOP", "any", 3);
|
||||||
|
|
||||||
bool seen = false;
|
bool seen = false;
|
||||||
conn->async_exec(req1, gresp, [&](auto ec, auto) mutable{
|
conn->async_exec(req1, gresp, [&](auto ec, auto) mutable {
|
||||||
// No error should occur since the cancelation should be
|
// No error should occur since the cancelation should be
|
||||||
// ignored.
|
// ignored.
|
||||||
std::cout << "async_exec (1): " << ec.message() << std::endl;
|
std::cout << "async_exec (1): " << ec.message() << std::endl;
|
||||||
@@ -90,8 +93,5 @@ BOOST_AUTO_TEST_CASE(test_ignore_explicit_cancel_of_req_written)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
BOOST_AUTO_TEST_CASE(dummy)
|
BOOST_AUTO_TEST_CASE(dummy) { BOOST_TEST(true); }
|
||||||
{
|
|
||||||
BOOST_TEST(true);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
|
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-exec-error
|
#define BOOST_TEST_MODULE conn_exec_error
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
@@ -38,7 +41,7 @@ BOOST_AUTO_TEST_CASE(no_ignore_error)
|
|||||||
|
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
conn->async_exec(req, ignore, [&](auto ec, auto){
|
conn->async_exec(req, ignore, [&](auto ec, auto) {
|
||||||
BOOST_CHECK_EQUAL(ec, error::resp3_simple_error);
|
BOOST_CHECK_EQUAL(ec, error::resp3_simple_error);
|
||||||
conn->cancel(operation::run);
|
conn->cancel(operation::run);
|
||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
@@ -65,7 +68,7 @@ BOOST_AUTO_TEST_CASE(has_diagnostic)
|
|||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
response<std::string, std::string> resp;
|
response<std::string, std::string> resp;
|
||||||
conn->async_exec(req, resp, [&](auto ec, auto){
|
conn->async_exec(req, resp, [&](auto ec, auto) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
|
|
||||||
// HELLO
|
// HELLO
|
||||||
@@ -106,8 +109,7 @@ BOOST_AUTO_TEST_CASE(resp3_error_in_cmd_pipeline)
|
|||||||
net::io_context ioc;
|
net::io_context ioc;
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
auto c2 = [&](auto ec, auto)
|
auto c2 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
BOOST_TEST(std::get<0>(resp2).has_value());
|
BOOST_TEST(std::get<0>(resp2).has_value());
|
||||||
BOOST_CHECK_EQUAL(std::get<0>(resp2).value(), "req2-msg1");
|
BOOST_CHECK_EQUAL(std::get<0>(resp2).value(), "req2-msg1");
|
||||||
@@ -115,8 +117,7 @@ BOOST_AUTO_TEST_CASE(resp3_error_in_cmd_pipeline)
|
|||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c1 = [&](auto ec, auto)
|
auto c1 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
BOOST_TEST(std::get<2>(resp1).has_error());
|
BOOST_TEST(std::get<2>(resp1).has_error());
|
||||||
BOOST_CHECK_EQUAL(std::get<2>(resp1).error().data_type, resp3::type::simple_error);
|
BOOST_CHECK_EQUAL(std::get<2>(resp1).error().data_type, resp3::type::simple_error);
|
||||||
@@ -155,14 +156,14 @@ BOOST_AUTO_TEST_CASE(error_in_transaction)
|
|||||||
ignore_t, // ping
|
ignore_t, // ping
|
||||||
response<std::string, std::string, std::string>, // exec
|
response<std::string, std::string, std::string>, // exec
|
||||||
std::string // ping
|
std::string // ping
|
||||||
> resp;
|
>
|
||||||
|
resp;
|
||||||
|
|
||||||
net::io_context ioc;
|
net::io_context ioc;
|
||||||
|
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
conn->async_exec(req, resp, [&](auto ec, auto){
|
conn->async_exec(req, resp, [&](auto ec, auto) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
|
|
||||||
BOOST_TEST(std::get<0>(resp).has_value());
|
BOOST_TEST(std::get<0>(resp).has_value());
|
||||||
@@ -178,7 +179,9 @@ BOOST_AUTO_TEST_CASE(error_in_transaction)
|
|||||||
|
|
||||||
// The ping in the transaction that should be an error.
|
// The ping in the transaction that should be an error.
|
||||||
BOOST_TEST(std::get<1>(std::get<5>(resp).value()).has_error());
|
BOOST_TEST(std::get<1>(std::get<5>(resp).value()).has_error());
|
||||||
BOOST_CHECK_EQUAL(std::get<1>(std::get<5>(resp).value()).error().data_type, resp3::type::simple_error);
|
BOOST_CHECK_EQUAL(
|
||||||
|
std::get<1>(std::get<5>(resp).value()).error().data_type,
|
||||||
|
resp3::type::simple_error);
|
||||||
auto const diag = std::get<1>(std::get<5>(resp).value()).error().diagnostic;
|
auto const diag = std::get<1>(std::get<5>(resp).value()).error().diagnostic;
|
||||||
BOOST_TEST(!std::empty(diag));
|
BOOST_TEST(!std::empty(diag));
|
||||||
|
|
||||||
@@ -225,14 +228,12 @@ BOOST_AUTO_TEST_CASE(subscriber_wrong_syntax)
|
|||||||
net::io_context ioc;
|
net::io_context ioc;
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
auto c2 = [&](auto ec, auto)
|
auto c2 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
std::cout << "async_exec: subscribe" << std::endl;
|
std::cout << "async_exec: subscribe" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c1 = [&](auto ec, auto)
|
auto c1 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
std::cout << "async_exec: hello" << std::endl;
|
std::cout << "async_exec: hello" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c2);
|
conn->async_exec(req2, ignore, c2);
|
||||||
@@ -243,8 +244,7 @@ BOOST_AUTO_TEST_CASE(subscriber_wrong_syntax)
|
|||||||
generic_response gresp;
|
generic_response gresp;
|
||||||
conn->set_receive_response(gresp);
|
conn->set_receive_response(gresp);
|
||||||
|
|
||||||
auto c3 = [&](auto ec, auto)
|
auto c3 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
std::cout << "async_receive" << std::endl;
|
std::cout << "async_receive" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
BOOST_TEST(gresp.has_error());
|
BOOST_TEST(gresp.has_error());
|
||||||
@@ -261,4 +261,3 @@ BOOST_AUTO_TEST_CASE(subscriber_wrong_syntax)
|
|||||||
|
|
||||||
ioc.run();
|
ioc.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/asio/awaitable.hpp>
|
#include <boost/asio/awaitable.hpp>
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
|
|
||||||
#define BOOST_TEST_MODULE conn-exec-retry
|
#define BOOST_TEST_MODULE conn_exec_retry
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
using error_code = boost::system::error_code;
|
using error_code = boost::system::error_code;
|
||||||
using connection = boost::redis::connection;
|
using connection = boost::redis::connection;
|
||||||
@@ -44,7 +47,7 @@ BOOST_AUTO_TEST_CASE(request_retry_false)
|
|||||||
|
|
||||||
net::steady_timer st{ioc};
|
net::steady_timer st{ioc};
|
||||||
st.expires_after(std::chrono::seconds{1});
|
st.expires_after(std::chrono::seconds{1});
|
||||||
st.async_wait([&](auto){
|
st.async_wait([&](auto) {
|
||||||
// Cancels the request before receiving the response. This
|
// Cancels the request before receiving the response. This
|
||||||
// should cause the third request to complete with error
|
// should cause the third request to complete with error
|
||||||
// although it has cancel_on_connection_lost = false. The reason
|
// although it has cancel_on_connection_lost = false. The reason
|
||||||
@@ -55,17 +58,17 @@ BOOST_AUTO_TEST_CASE(request_retry_false)
|
|||||||
std::cout << "async_wait" << std::endl;
|
std::cout << "async_wait" << std::endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto c2 = [&](auto ec, auto){
|
auto c2 = [&](auto ec, auto) {
|
||||||
std::cout << "c2" << std::endl;
|
std::cout << "c2" << std::endl;
|
||||||
BOOST_CHECK_EQUAL(ec, boost::asio::error::operation_aborted);
|
BOOST_CHECK_EQUAL(ec, boost::asio::error::operation_aborted);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c1 = [&](auto ec, auto){
|
auto c1 = [&](auto ec, auto) {
|
||||||
std::cout << "c1" << std::endl;
|
std::cout << "c1" << std::endl;
|
||||||
BOOST_CHECK_EQUAL(ec, boost::asio::error::operation_aborted);
|
BOOST_CHECK_EQUAL(ec, boost::asio::error::operation_aborted);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c0 = [&](auto ec, auto){
|
auto c0 = [&](auto ec, auto) {
|
||||||
std::cout << "c0" << std::endl;
|
std::cout << "c0" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req1, ignore, c1);
|
conn->async_exec(req1, ignore, c1);
|
||||||
@@ -75,13 +78,13 @@ BOOST_AUTO_TEST_CASE(request_retry_false)
|
|||||||
conn->async_exec(req0, ignore, c0);
|
conn->async_exec(req0, ignore, c0);
|
||||||
|
|
||||||
auto cfg = make_test_config();
|
auto cfg = make_test_config();
|
||||||
conn->async_run(cfg, {boost::redis::logger::level::debug},
|
conn->async_run(
|
||||||
[&](boost::system::error_code const& ec)
|
cfg,
|
||||||
{
|
{boost::redis::logger::level::debug},
|
||||||
|
[&](boost::system::error_code const& ec) {
|
||||||
std::cout << "async_run: " << ec.message() << std::endl;
|
std::cout << "async_run: " << ec.message() << std::endl;
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
ioc.run();
|
ioc.run();
|
||||||
}
|
}
|
||||||
@@ -111,7 +114,7 @@ BOOST_AUTO_TEST_CASE(request_retry_true)
|
|||||||
|
|
||||||
net::steady_timer st{ioc};
|
net::steady_timer st{ioc};
|
||||||
st.expires_after(std::chrono::seconds{1});
|
st.expires_after(std::chrono::seconds{1});
|
||||||
st.async_wait([&](auto){
|
st.async_wait([&](auto) {
|
||||||
// Cancels the request before receiving the response. This
|
// Cancels the request before receiving the response. This
|
||||||
// should cause the third request to not complete with error
|
// should cause the third request to not complete with error
|
||||||
// since it has cancel_if_unresponded = true and cancellation
|
// since it has cancel_if_unresponded = true and cancellation
|
||||||
@@ -119,22 +122,22 @@ BOOST_AUTO_TEST_CASE(request_retry_true)
|
|||||||
conn->cancel(operation::run);
|
conn->cancel(operation::run);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto c3 = [&](auto ec, auto){
|
auto c3 = [&](auto ec, auto) {
|
||||||
std::cout << "c3: " << ec.message() << std::endl;
|
std::cout << "c3: " << ec.message() << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c2 = [&](auto ec, auto){
|
auto c2 = [&](auto ec, auto) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req3, ignore, c3);
|
conn->async_exec(req3, ignore, c3);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c1 = [](auto ec, auto){
|
auto c1 = [](auto ec, auto) {
|
||||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c0 = [&](auto ec, auto){
|
auto c0 = [&](auto ec, auto) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req1, ignore, c1);
|
conn->async_exec(req1, ignore, c1);
|
||||||
conn->async_exec(req2, ignore, c2);
|
conn->async_exec(req2, ignore, c2);
|
||||||
@@ -144,7 +147,7 @@ BOOST_AUTO_TEST_CASE(request_retry_true)
|
|||||||
|
|
||||||
auto cfg = make_test_config();
|
auto cfg = make_test_config();
|
||||||
cfg.health_check_interval = 5s;
|
cfg.health_check_interval = 5s;
|
||||||
conn->async_run(cfg, {}, [&](auto ec){
|
conn->async_run(cfg, {}, [&](auto ec) {
|
||||||
std::cout << ec.message() << std::endl;
|
std::cout << ec.message() << std::endl;
|
||||||
BOOST_TEST(!!ec);
|
BOOST_TEST(!!ec);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,15 +6,18 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
#include <boost/system/errc.hpp>
|
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
|
||||||
#include <boost/asio/as_tuple.hpp>
|
#include <boost/asio/as_tuple.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-push
|
#include <boost/asio/co_spawn.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/system/errc.hpp>
|
||||||
|
#define BOOST_TEST_MODULE conn - push
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
namespace redis = boost::redis;
|
namespace redis = boost::redis;
|
||||||
|
|
||||||
@@ -47,19 +50,16 @@ BOOST_AUTO_TEST_CASE(receives_push_waiting_resps)
|
|||||||
|
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
auto c3 =[](auto ec, auto...)
|
auto c3 = [](auto ec, auto...) {
|
||||||
{
|
|
||||||
std::cout << "c3: " << ec.message() << std::endl;
|
std::cout << "c3: " << ec.message() << std::endl;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c2 =[&, conn](auto ec, auto...)
|
auto c2 = [&, conn](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req3, ignore, c3);
|
conn->async_exec(req3, ignore, c3);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c1 =[&, conn](auto ec, auto...)
|
auto c1 = [&, conn](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c2);
|
conn->async_exec(req2, ignore, c2);
|
||||||
};
|
};
|
||||||
@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(receives_push_waiting_resps)
|
|||||||
run(conn, make_test_config(), {});
|
run(conn, make_test_config(), {});
|
||||||
|
|
||||||
bool push_received = false;
|
bool push_received = false;
|
||||||
conn->async_receive([&, conn](auto ec, auto){
|
conn->async_receive([&, conn](auto ec, auto) {
|
||||||
std::cout << "async_receive" << std::endl;
|
std::cout << "async_receive" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
push_received = true;
|
push_received = true;
|
||||||
@@ -94,13 +94,13 @@ BOOST_AUTO_TEST_CASE(push_received1)
|
|||||||
req.push("SUBSCRIBE", "channel1");
|
req.push("SUBSCRIBE", "channel1");
|
||||||
req.push("SUBSCRIBE", "channel2");
|
req.push("SUBSCRIBE", "channel2");
|
||||||
|
|
||||||
conn->async_exec(req, ignore, [conn](auto ec, auto){
|
conn->async_exec(req, ignore, [conn](auto ec, auto) {
|
||||||
std::cout << "async_exec" << std::endl;
|
std::cout << "async_exec" << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
});
|
});
|
||||||
|
|
||||||
bool push_async_received = false;
|
bool push_async_received = false;
|
||||||
conn->async_receive([&, conn](auto ec, auto){
|
conn->async_receive([&, conn](auto ec, auto) {
|
||||||
std::cout << "(1) async_receive" << std::endl;
|
std::cout << "(1) async_receive" << std::endl;
|
||||||
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
@@ -116,7 +116,9 @@ BOOST_AUTO_TEST_CASE(push_received1)
|
|||||||
// Tries to receive a third push synchronously.
|
// Tries to receive a third push synchronously.
|
||||||
ec2 = {};
|
ec2 = {};
|
||||||
res = conn->receive(ec2);
|
res = conn->receive(ec2);
|
||||||
BOOST_CHECK_EQUAL(ec2, boost::redis::make_error_code(boost::redis::error::sync_receive_push_failed));
|
BOOST_CHECK_EQUAL(
|
||||||
|
ec2,
|
||||||
|
boost::redis::make_error_code(boost::redis::error::sync_receive_push_failed));
|
||||||
|
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
});
|
});
|
||||||
@@ -139,11 +141,11 @@ BOOST_AUTO_TEST_CASE(push_filtered_out)
|
|||||||
req.push("QUIT");
|
req.push("QUIT");
|
||||||
|
|
||||||
response<ignore_t, std::string, std::string> resp;
|
response<ignore_t, std::string, std::string> resp;
|
||||||
conn->async_exec(req, resp, [conn](auto ec, auto){
|
conn->async_exec(req, resp, [conn](auto ec, auto) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
});
|
});
|
||||||
|
|
||||||
conn->async_receive([&, conn](auto ec, auto){
|
conn->async_receive([&, conn](auto ec, auto) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
});
|
});
|
||||||
@@ -157,8 +159,7 @@ BOOST_AUTO_TEST_CASE(push_filtered_out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
||||||
net::awaitable<void>
|
net::awaitable<void> push_consumer1(std::shared_ptr<connection> conn, bool& push_received)
|
||||||
push_consumer1(std::shared_ptr<connection> conn, bool& push_received)
|
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto [ec, ev] = co_await conn->async_receive(as_tuple(net::use_awaitable));
|
auto [ec, ev] = co_await conn->async_receive(as_tuple(net::use_awaitable));
|
||||||
@@ -173,26 +174,26 @@ push_consumer1(std::shared_ptr<connection> conn, bool& push_received)
|
|||||||
push_received = true;
|
push_received = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct response_error_tag{};
|
struct response_error_tag { };
|
||||||
response_error_tag error_tag_obj;
|
response_error_tag error_tag_obj;
|
||||||
|
|
||||||
struct response_error_adapter {
|
struct response_error_adapter {
|
||||||
void
|
void operator()(
|
||||||
operator()(
|
std::size_t,
|
||||||
std::size_t, boost::redis::resp3::basic_node<std::string_view> const&, boost::system::error_code& ec)
|
boost::redis::resp3::basic_node<std::string_view> const&,
|
||||||
|
boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
ec = boost::redis::error::incompatible_size;
|
ec = boost::redis::error::incompatible_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
auto get_supported_response_size() const noexcept
|
auto get_supported_response_size() const noexcept
|
||||||
{ return static_cast<std::size_t>(-1);}
|
{
|
||||||
|
return static_cast<std::size_t>(-1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto boost_redis_adapt(response_error_tag&)
|
auto boost_redis_adapt(response_error_tag&) { return response_error_adapter{}; }
|
||||||
{
|
|
||||||
return response_error_adapter{};
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_push_adapter)
|
BOOST_AUTO_TEST_CASE(test_push_adapter)
|
||||||
{
|
{
|
||||||
@@ -212,12 +213,12 @@ BOOST_AUTO_TEST_CASE(test_push_adapter)
|
|||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
});
|
});
|
||||||
|
|
||||||
conn->async_exec(req, ignore, [](auto ec, auto){
|
conn->async_exec(req, ignore, [](auto ec, auto) {
|
||||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto cfg = make_test_config();
|
auto cfg = make_test_config();
|
||||||
conn->async_run(cfg, {}, [](auto ec){
|
conn->async_run(cfg, {}, [](auto ec) {
|
||||||
BOOST_CHECK_EQUAL(ec, redis::error::incompatible_size);
|
BOOST_CHECK_EQUAL(ec, redis::error::incompatible_size);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -255,63 +256,51 @@ BOOST_AUTO_TEST_CASE(many_subscribers)
|
|||||||
net::io_context ioc;
|
net::io_context ioc;
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
|
|
||||||
auto c11 =[&](auto ec, auto...)
|
auto c11 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
std::cout << "quit sent: " << ec.message() << std::endl;
|
std::cout << "quit sent: " << ec.message() << std::endl;
|
||||||
conn->cancel(operation::reconnection);
|
conn->cancel(operation::reconnection);
|
||||||
};
|
};
|
||||||
auto c10 =[&](auto ec, auto...)
|
auto c10 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req3, ignore, c11);
|
conn->async_exec(req3, ignore, c11);
|
||||||
};
|
};
|
||||||
auto c9 =[&](auto ec, auto...)
|
auto c9 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c10);
|
conn->async_exec(req2, ignore, c10);
|
||||||
};
|
};
|
||||||
auto c8 =[&](auto ec, auto...)
|
auto c8 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req1, ignore, c9);
|
conn->async_exec(req1, ignore, c9);
|
||||||
};
|
};
|
||||||
auto c7 =[&](auto ec, auto...)
|
auto c7 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c8);
|
conn->async_exec(req2, ignore, c8);
|
||||||
};
|
};
|
||||||
auto c6 =[&](auto ec, auto...)
|
auto c6 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c7);
|
conn->async_exec(req2, ignore, c7);
|
||||||
};
|
};
|
||||||
auto c5 =[&](auto ec, auto...)
|
auto c5 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req1, ignore, c6);
|
conn->async_exec(req1, ignore, c6);
|
||||||
};
|
};
|
||||||
auto c4 =[&](auto ec, auto...)
|
auto c4 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c5);
|
conn->async_exec(req2, ignore, c5);
|
||||||
};
|
};
|
||||||
auto c3 =[&](auto ec, auto...)
|
auto c3 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req1, ignore, c4);
|
conn->async_exec(req1, ignore, c4);
|
||||||
};
|
};
|
||||||
auto c2 =[&](auto ec, auto...)
|
auto c2 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c3);
|
conn->async_exec(req2, ignore, c3);
|
||||||
};
|
};
|
||||||
auto c1 =[&](auto ec, auto...)
|
auto c1 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c2);
|
conn->async_exec(req2, ignore, c2);
|
||||||
};
|
};
|
||||||
auto c0 =[&](auto ec, auto...)
|
auto c0 = [&](auto ec, auto...) {
|
||||||
{
|
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req1, ignore, c1);
|
conn->async_exec(req1, ignore, c1);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,12 +5,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/system/errc.hpp>
|
#include <boost/system/errc.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-quit
|
#define BOOST_TEST_MODULE conn_quit
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
using boost::redis::connection;
|
using boost::redis::connection;
|
||||||
using boost::system::error_code;
|
using boost::system::error_code;
|
||||||
@@ -40,21 +43,18 @@ BOOST_AUTO_TEST_CASE(test_async_run_exits)
|
|||||||
req3.get_config().cancel_if_not_connected = true;
|
req3.get_config().cancel_if_not_connected = true;
|
||||||
req3.push("PING");
|
req3.push("PING");
|
||||||
|
|
||||||
auto c3 = [](auto ec, auto)
|
auto c3 = [](auto ec, auto) {
|
||||||
{
|
|
||||||
std::clog << "c3: " << ec.message() << std::endl;
|
std::clog << "c3: " << ec.message() << std::endl;
|
||||||
BOOST_CHECK_EQUAL(ec, boost::asio::error::operation_aborted);
|
BOOST_CHECK_EQUAL(ec, boost::asio::error::operation_aborted);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c2 = [&](auto ec, auto)
|
auto c2 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
std::clog << "c2: " << ec.message() << std::endl;
|
std::clog << "c2: " << ec.message() << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req3, ignore, c3);
|
conn->async_exec(req3, ignore, c3);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto c1 = [&](auto ec, auto)
|
auto c1 = [&](auto ec, auto) {
|
||||||
{
|
|
||||||
std::cout << "c1: " << ec.message() << std::endl;
|
std::cout << "c1: " << ec.message() << std::endl;
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
conn->async_exec(req2, ignore, c2);
|
conn->async_exec(req2, ignore, c2);
|
||||||
@@ -71,4 +71,3 @@ BOOST_AUTO_TEST_CASE(test_async_run_exits)
|
|||||||
|
|
||||||
ioc.run();
|
ioc.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-reconnect
|
#define BOOST_TEST_MODULE conn_reconnect
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
||||||
#include <boost/asio/experimental/awaitable_operators.hpp>
|
#include <boost/asio/experimental/awaitable_operators.hpp>
|
||||||
|
|
||||||
@@ -43,7 +46,8 @@ net::awaitable<void> test_reconnect_impl()
|
|||||||
logger l;
|
logger l;
|
||||||
co_await conn->async_exec(req, ignore, net::redirect_error(net::use_awaitable, ec1));
|
co_await conn->async_exec(req, ignore, net::redirect_error(net::use_awaitable, ec1));
|
||||||
//BOOST_TEST(!ec);
|
//BOOST_TEST(!ec);
|
||||||
std::cout << "test_reconnect: " << i << " " << ec2.message() << " " << ec1.message() << std::endl;
|
std::cout << "test_reconnect: " << i << " " << ec2.message() << " " << ec1.message()
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
@@ -76,10 +80,7 @@ auto async_test_reconnect_timeout() -> net::awaitable<void>
|
|||||||
|
|
||||||
st.expires_after(std::chrono::seconds{1});
|
st.expires_after(std::chrono::seconds{1});
|
||||||
auto cfg = make_test_config();
|
auto cfg = make_test_config();
|
||||||
co_await (
|
co_await (conn->async_exec(req1, ignore, redir(ec1)) || st.async_wait(redir(ec3)));
|
||||||
conn->async_exec(req1, ignore, redir(ec1)) ||
|
|
||||||
st.async_wait(redir(ec3))
|
|
||||||
);
|
|
||||||
|
|
||||||
//BOOST_TEST(!ec1);
|
//BOOST_TEST(!ec1);
|
||||||
//BOOST_TEST(!ec3);
|
//BOOST_TEST(!ec3);
|
||||||
@@ -87,14 +88,13 @@ auto async_test_reconnect_timeout() -> net::awaitable<void>
|
|||||||
request req2;
|
request req2;
|
||||||
req2.get_config().cancel_if_not_connected = false;
|
req2.get_config().cancel_if_not_connected = false;
|
||||||
req2.get_config().cancel_on_connection_lost = true;
|
req2.get_config().cancel_on_connection_lost = true;
|
||||||
req2.get_config().cancel_if_unresponded= true;
|
req2.get_config().cancel_if_unresponded = true;
|
||||||
req2.push("QUIT");
|
req2.push("QUIT");
|
||||||
|
|
||||||
st.expires_after(std::chrono::seconds{1});
|
st.expires_after(std::chrono::seconds{1});
|
||||||
co_await (
|
co_await (
|
||||||
conn->async_exec(req1, ignore, net::redirect_error(net::use_awaitable, ec1)) ||
|
conn->async_exec(req1, ignore, net::redirect_error(net::use_awaitable, ec1)) ||
|
||||||
st.async_wait(net::redirect_error(net::use_awaitable, ec3))
|
st.async_wait(net::redirect_error(net::use_awaitable, ec3)));
|
||||||
);
|
|
||||||
conn->cancel();
|
conn->cancel();
|
||||||
|
|
||||||
std::cout << "ccc" << std::endl;
|
std::cout << "ccc" << std::endl;
|
||||||
@@ -109,8 +109,5 @@ BOOST_AUTO_TEST_CASE(test_reconnect_and_idle)
|
|||||||
ioc.run();
|
ioc.run();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
BOOST_AUTO_TEST_CASE(dummy)
|
BOOST_AUTO_TEST_CASE(dummy) { BOOST_TEST(true); }
|
||||||
{
|
|
||||||
BOOST_TEST(true);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/asio/ssl/host_name_verification.hpp>
|
#include <boost/asio/ssl/host_name_verification.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
#include <boost/redis/connection.hpp>
|
#define BOOST_TEST_MODULE conn_tls
|
||||||
#define BOOST_TEST_MODULE conn-tls
|
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "boost/system/detail/error_code.hpp"
|
#include "boost/system/detail/error_code.hpp"
|
||||||
#define BOOST_TEST_MODULE conversions
|
#define BOOST_TEST_MODULE conversions
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
|
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
@@ -43,8 +44,8 @@ BOOST_AUTO_TEST_CASE(ints)
|
|||||||
long,
|
long,
|
||||||
unsigned long,
|
unsigned long,
|
||||||
long long,
|
long long,
|
||||||
unsigned long long
|
unsigned long long>
|
||||||
> resp;
|
resp;
|
||||||
|
|
||||||
conn->async_exec(req, resp, [conn](error_code ec, std::size_t) {
|
conn->async_exec(req, resp, [conn](error_code ec, std::size_t) {
|
||||||
BOOST_TEST(!ec);
|
BOOST_TEST(!ec);
|
||||||
|
|||||||
@@ -6,16 +6,19 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
|
|
||||||
#include <boost/asio/awaitable.hpp>
|
#include <boost/asio/awaitable.hpp>
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-quit
|
#define BOOST_TEST_MODULE conn_quit
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common.hpp"
|
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
using boost::redis::request;
|
using boost::redis::request;
|
||||||
@@ -40,7 +43,7 @@ BOOST_AUTO_TEST_CASE(issue_181)
|
|||||||
net::steady_timer timer{ioc};
|
net::steady_timer timer{ioc};
|
||||||
timer.expires_after(std::chrono::seconds{1});
|
timer.expires_after(std::chrono::seconds{1});
|
||||||
|
|
||||||
auto run_cont = [&](auto ec){
|
auto run_cont = [&](auto ec) {
|
||||||
std::cout << "async_run1: " << ec.message() << std::endl;
|
std::cout << "async_run1: " << ec.message() << std::endl;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,7 +54,7 @@ BOOST_AUTO_TEST_CASE(issue_181)
|
|||||||
BOOST_TEST(!conn.run_is_canceled());
|
BOOST_TEST(!conn.run_is_canceled());
|
||||||
|
|
||||||
// Uses a timer to wait some time until run has been called.
|
// Uses a timer to wait some time until run has been called.
|
||||||
auto timer_cont = [&](auto ec){
|
auto timer_cont = [&](auto ec) {
|
||||||
std::cout << "timer_cont: " << ec.message() << std::endl;
|
std::cout << "timer_cont: " << ec.message() << std::endl;
|
||||||
BOOST_TEST(!conn.run_is_canceled());
|
BOOST_TEST(!conn.run_is_canceled());
|
||||||
conn.cancel(operation::run);
|
conn.cancel(operation::run);
|
||||||
|
|||||||
@@ -8,19 +8,22 @@
|
|||||||
|
|
||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#include <boost/redis/logger.hpp>
|
#include <boost/redis/logger.hpp>
|
||||||
|
|
||||||
#include <boost/asio/as_tuple.hpp>
|
#include <boost/asio/as_tuple.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
|
||||||
#include <boost/asio/consign.hpp>
|
|
||||||
#include <boost/asio/redirect_error.hpp>
|
|
||||||
#include <boost/asio/awaitable.hpp>
|
#include <boost/asio/awaitable.hpp>
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-quit
|
#include <boost/asio/consign.hpp>
|
||||||
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/asio/redirect_error.hpp>
|
||||||
|
#include <boost/asio/use_awaitable.hpp>
|
||||||
|
#define BOOST_TEST_MODULE conn - quit
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <tuple>
|
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
@@ -38,8 +41,7 @@ using boost::asio::redirect_error;
|
|||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
// Push consumer
|
// Push consumer
|
||||||
auto
|
auto receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
||||||
receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
|
||||||
{
|
{
|
||||||
std::cout << "uuu" << std::endl;
|
std::cout << "uuu" << std::endl;
|
||||||
while (conn->will_reconnect()) {
|
while (conn->will_reconnect()) {
|
||||||
@@ -59,8 +61,7 @@ receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
|||||||
std::cout << "Exiting the receiver." << std::endl;
|
std::cout << "Exiting the receiver." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto
|
auto periodic_task(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
||||||
periodic_task(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
|
||||||
{
|
{
|
||||||
net::steady_timer timer{co_await net::this_coro::executor};
|
net::steady_timer timer{co_await net::this_coro::executor};
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
@@ -107,8 +108,6 @@ BOOST_AUTO_TEST_CASE(issue_50)
|
|||||||
|
|
||||||
#else // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#else // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(issue_50)
|
BOOST_AUTO_TEST_CASE(issue_50) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||||
|
|||||||
@@ -4,17 +4,18 @@
|
|||||||
* accompanying file LICENSE.txt)
|
* accompanying file LICENSE.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/redis/detail/resp3_handshaker.hpp>
|
|
||||||
#include <boost/redis/detail/multiplexer.hpp>
|
|
||||||
#include <boost/redis/resp3/serialization.hpp>
|
|
||||||
#include <boost/redis/resp3/node.hpp>
|
|
||||||
#include <boost/redis/resp3/type.hpp>
|
|
||||||
#include <boost/redis/adapter/adapt.hpp>
|
#include <boost/redis/adapter/adapt.hpp>
|
||||||
#include <boost/redis/adapter/any_adapter.hpp>
|
#include <boost/redis/adapter/any_adapter.hpp>
|
||||||
#define BOOST_TEST_MODULE conn-quit
|
#include <boost/redis/detail/multiplexer.hpp>
|
||||||
|
#include <boost/redis/detail/resp3_handshaker.hpp>
|
||||||
|
#include <boost/redis/resp3/node.hpp>
|
||||||
|
#include <boost/redis/resp3/serialization.hpp>
|
||||||
|
#include <boost/redis/resp3/type.hpp>
|
||||||
|
#define BOOST_TEST_MODULE conn_quit
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
using boost::redis::request;
|
using boost::redis::request;
|
||||||
using boost::redis::config;
|
using boost::redis::config;
|
||||||
@@ -38,7 +39,7 @@ BOOST_AUTO_TEST_CASE(low_level_sync_sans_io)
|
|||||||
char const* wire = "~6\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n+orange\r\n";
|
char const* wire = "~6\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n+orange\r\n";
|
||||||
deserialize(wire, adapt2(resp));
|
deserialize(wire, adapt2(resp));
|
||||||
|
|
||||||
for (auto const& e: resp.value())
|
for (auto const& e : resp.value())
|
||||||
std::cout << e << std::endl;
|
std::cout << e << std::endl;
|
||||||
|
|
||||||
} catch (std::exception const& e) {
|
} catch (std::exception const& e) {
|
||||||
@@ -82,7 +83,8 @@ BOOST_AUTO_TEST_CASE(config_to_hello_cmd_clientname)
|
|||||||
|
|
||||||
push_hello(cfg, req);
|
push_hello(cfg, req);
|
||||||
|
|
||||||
std::string_view const expected = "*4\r\n$5\r\nHELLO\r\n$1\r\n3\r\n$7\r\nSETNAME\r\n$11\r\nBoost.Redis\r\n";
|
std::string_view const
|
||||||
|
expected = "*4\r\n$5\r\nHELLO\r\n$1\r\n3\r\n$7\r\nSETNAME\r\n$11\r\nBoost.Redis\r\n";
|
||||||
BOOST_CHECK_EQUAL(req.payload(), expected);
|
BOOST_CHECK_EQUAL(req.payload(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,21 +98,20 @@ BOOST_AUTO_TEST_CASE(config_to_hello_cmd_auth)
|
|||||||
|
|
||||||
push_hello(cfg, req);
|
push_hello(cfg, req);
|
||||||
|
|
||||||
std::string_view const expected = "*5\r\n$5\r\nHELLO\r\n$1\r\n3\r\n$4\r\nAUTH\r\n$3\r\nfoo\r\n$3\r\nbar\r\n";
|
std::string_view const
|
||||||
|
expected = "*5\r\n$5\r\nHELLO\r\n$1\r\n3\r\n$4\r\nAUTH\r\n$3\r\nfoo\r\n$3\r\nbar\r\n";
|
||||||
BOOST_CHECK_EQUAL(req.payload(), expected);
|
BOOST_CHECK_EQUAL(req.payload(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(issue_210_empty_set)
|
BOOST_AUTO_TEST_CASE(issue_210_empty_set)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
result<
|
result<std::tuple<
|
||||||
std::tuple<
|
|
||||||
result<int>,
|
result<int>,
|
||||||
result<std::vector<std::string>>,
|
result<std::vector<std::string>>,
|
||||||
result<std::string>,
|
result<std::string>,
|
||||||
result<int>
|
result<int>>>
|
||||||
>
|
resp;
|
||||||
> resp;
|
|
||||||
|
|
||||||
char const* wire = "*4\r\n:1\r\n~0\r\n$25\r\nthis_should_not_be_in_set\r\n:2\r\n";
|
char const* wire = "*4\r\n:1\r\n~0\r\n$25\r\nthis_should_not_be_in_set\r\n:2\r\n";
|
||||||
|
|
||||||
@@ -130,16 +131,15 @@ BOOST_AUTO_TEST_CASE(issue_210_empty_set)
|
|||||||
BOOST_AUTO_TEST_CASE(issue_210_non_empty_set_size_one)
|
BOOST_AUTO_TEST_CASE(issue_210_non_empty_set_size_one)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
result<
|
result<std::tuple<
|
||||||
std::tuple<
|
|
||||||
result<int>,
|
result<int>,
|
||||||
result<std::vector<std::string>>,
|
result<std::vector<std::string>>,
|
||||||
result<std::string>,
|
result<std::string>,
|
||||||
result<int>
|
result<int>>>
|
||||||
>
|
resp;
|
||||||
> resp;
|
|
||||||
|
|
||||||
char const* wire = "*4\r\n:1\r\n~1\r\n$3\r\nfoo\r\n$25\r\nthis_should_not_be_in_set\r\n:2\r\n";
|
char const*
|
||||||
|
wire = "*4\r\n:1\r\n~1\r\n$3\r\nfoo\r\n$25\r\nthis_should_not_be_in_set\r\n:2\r\n";
|
||||||
|
|
||||||
deserialize(wire, adapt2(resp));
|
deserialize(wire, adapt2(resp));
|
||||||
|
|
||||||
@@ -158,16 +158,15 @@ BOOST_AUTO_TEST_CASE(issue_210_non_empty_set_size_one)
|
|||||||
BOOST_AUTO_TEST_CASE(issue_210_non_empty_set_size_two)
|
BOOST_AUTO_TEST_CASE(issue_210_non_empty_set_size_two)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
result<
|
result<std::tuple<
|
||||||
std::tuple<
|
|
||||||
result<int>,
|
result<int>,
|
||||||
result<std::vector<std::string>>,
|
result<std::vector<std::string>>,
|
||||||
result<std::string>,
|
result<std::string>,
|
||||||
result<int>
|
result<int>>>
|
||||||
>
|
resp;
|
||||||
> resp;
|
|
||||||
|
|
||||||
char const* wire = "*4\r\n:1\r\n~2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$25\r\nthis_should_not_be_in_set\r\n:2\r\n";
|
char const* wire =
|
||||||
|
"*4\r\n:1\r\n~2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$25\r\nthis_should_not_be_in_set\r\n:2\r\n";
|
||||||
|
|
||||||
deserialize(wire, adapt2(resp));
|
deserialize(wire, adapt2(resp));
|
||||||
|
|
||||||
@@ -185,16 +184,11 @@ BOOST_AUTO_TEST_CASE(issue_210_non_empty_set_size_two)
|
|||||||
BOOST_AUTO_TEST_CASE(issue_210_no_nested)
|
BOOST_AUTO_TEST_CASE(issue_210_no_nested)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
result<
|
result<std::tuple<result<int>, result<std::string>, result<std::string>, result<std::string>>>
|
||||||
std::tuple<
|
resp;
|
||||||
result<int>,
|
|
||||||
result<std::string>,
|
|
||||||
result<std::string>,
|
|
||||||
result<std::string>
|
|
||||||
>
|
|
||||||
> resp;
|
|
||||||
|
|
||||||
char const* wire = "*4\r\n:1\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$25\r\nthis_should_not_be_in_set\r\n";
|
char const*
|
||||||
|
wire = "*4\r\n:1\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$25\r\nthis_should_not_be_in_set\r\n";
|
||||||
|
|
||||||
deserialize(wire, adapt2(resp));
|
deserialize(wire, adapt2(resp));
|
||||||
|
|
||||||
@@ -278,7 +272,7 @@ BOOST_AUTO_TEST_CASE(multiplexer_push)
|
|||||||
BOOST_CHECK_EQUAL(resp.value().at(1).value, "one");
|
BOOST_CHECK_EQUAL(resp.value().at(1).value, "one");
|
||||||
BOOST_CHECK_EQUAL(resp.value().at(2).value, "two");
|
BOOST_CHECK_EQUAL(resp.value().at(2).value, "two");
|
||||||
|
|
||||||
for (auto const& e: resp.value())
|
for (auto const& e : resp.value())
|
||||||
std::cout << e << std::endl;
|
std::cout << e << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +375,7 @@ BOOST_AUTO_TEST_CASE(multiplexer_pipeline)
|
|||||||
// The done status should still be unchanged on requests that
|
// The done status should still be unchanged on requests that
|
||||||
// expect a response.
|
// expect a response.
|
||||||
BOOST_TEST(!item1.done);
|
BOOST_TEST(!item1.done);
|
||||||
BOOST_TEST( item2.done);
|
BOOST_TEST(item2.done);
|
||||||
BOOST_TEST(!item3.done);
|
BOOST_TEST(!item3.done);
|
||||||
|
|
||||||
// Simulates a socket read by putting some data in the read buffer.
|
// Simulates a socket read by putting some data in the read buffer.
|
||||||
@@ -399,8 +393,8 @@ BOOST_AUTO_TEST_CASE(multiplexer_pipeline)
|
|||||||
BOOST_TEST(mpx.get_read_buffer().empty());
|
BOOST_TEST(mpx.get_read_buffer().empty());
|
||||||
|
|
||||||
// The last request still did not get a response.
|
// The last request still did not get a response.
|
||||||
BOOST_TEST( item1.done);
|
BOOST_TEST(item1.done);
|
||||||
BOOST_TEST( item2.done);
|
BOOST_TEST(item2.done);
|
||||||
BOOST_TEST(!item3.done);
|
BOOST_TEST(!item3.done);
|
||||||
|
|
||||||
// TODO: Check the first request was removed from the queue.
|
// TODO: Check the first request was removed from the queue.
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define BOOST_TEST_MODULE request
|
#define BOOST_TEST_MODULE request
|
||||||
#include <boost/test/included/unit_test.hpp>
|
|
||||||
|
|
||||||
#include <boost/redis/request.hpp>
|
#include <boost/redis/request.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
|
||||||
using boost::redis::request;
|
using boost::redis::request;
|
||||||
|
|
||||||
// TODO: Serialization.
|
// TODO: Serialization.
|
||||||
@@ -39,9 +39,14 @@ BOOST_AUTO_TEST_CASE(multiple_args)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(container_and_range)
|
BOOST_AUTO_TEST_CASE(container_and_range)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string> in{{"key1", "value1"}, {"key2", "value2"}};
|
std::map<std::string, std::string> in{
|
||||||
|
{"key1", "value1"},
|
||||||
|
{"key2", "value2"}
|
||||||
|
};
|
||||||
|
|
||||||
char const* res = "*6\r\n$4\r\nHSET\r\n$3\r\nkey\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n";
|
char const* res =
|
||||||
|
"*6\r\n$4\r\nHSET\r\n$3\r\nkey\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$"
|
||||||
|
"6\r\nvalue2\r\n";
|
||||||
|
|
||||||
request req1;
|
request req1;
|
||||||
req1.push_range("HSET", "key", in);
|
req1.push_range("HSET", "key", in);
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
#include <boost/redis/connection.hpp>
|
#include <boost/redis/connection.hpp>
|
||||||
#define BOOST_TEST_MODULE run
|
#define BOOST_TEST_MODULE run
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace net = boost::asio;
|
namespace net = boost::asio;
|
||||||
namespace redis = boost::redis;
|
namespace redis = boost::redis;
|
||||||
|
|
||||||
@@ -22,8 +24,10 @@ using namespace std::chrono_literals;
|
|||||||
|
|
||||||
bool is_host_not_found(error_code ec)
|
bool is_host_not_found(error_code ec)
|
||||||
{
|
{
|
||||||
if (ec == net::error::netdb_errors::host_not_found) return true;
|
if (ec == net::error::netdb_errors::host_not_found)
|
||||||
if (ec == net::error::netdb_errors::host_not_found_try_again) return true;
|
return true;
|
||||||
|
if (ec == net::error::netdb_errors::host_not_found_try_again)
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +44,7 @@ BOOST_AUTO_TEST_CASE(resolve_bad_host)
|
|||||||
cfg.reconnect_wait_interval = 0s;
|
cfg.reconnect_wait_interval = 0s;
|
||||||
|
|
||||||
auto conn = std::make_shared<connection>(ioc);
|
auto conn = std::make_shared<connection>(ioc);
|
||||||
conn->async_run(cfg, {}, [](auto ec){
|
conn->async_run(cfg, {}, [](auto ec) {
|
||||||
BOOST_TEST(is_host_not_found(ec));
|
BOOST_TEST(is_host_not_found(ec));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -97,4 +101,3 @@ BOOST_AUTO_TEST_CASE(connect_bad_port)
|
|||||||
// run(conn, cfg, boost::redis::error::connect_timeout);
|
// run(conn, cfg, boost::redis::error::connect_timeout);
|
||||||
// ioc.run();
|
// ioc.run();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user