From 06d88477bd06cdd8fce0f7128c38cc670536a21f Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 7 Aug 2019 14:15:01 +0200 Subject: [PATCH] RedisConnection: forward I/O errors to async-ly waiting requestors refs #50 --- lib/redis/redisconnection.cpp | 44 +++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/lib/redis/redisconnection.cpp b/lib/redis/redisconnection.cpp index 86187d2fc..22c3f43da 100644 --- a/lib/redis/redisconnection.cpp +++ b/lib/redis/redisconnection.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -169,7 +170,18 @@ void RedisConnection::ReadLoop(asio::yield_context& yc) auto promise (std::move(m_Queues.ReplyPromises.front())); m_Queues.ReplyPromises.pop(); - promise.set_value(ReadOne(yc)); + Reply reply; + + try { + reply = ReadOne(yc); + } catch (const boost::coroutines::detail::forced_unwind&) { + throw; + } catch (...) { + promise.set_exception(std::current_exception()); + throw; + } + + promise.set_value(std::move(reply)); } break; case ResponseAction::DeliverBulk: @@ -181,7 +193,14 @@ void RedisConnection::ReadLoop(asio::yield_context& yc) replies.reserve(item.Amount); for (auto i (item.Amount); i; --i) { - replies.emplace_back(ReadOne(yc)); + try { + replies.emplace_back(ReadOne(yc)); + } catch (const boost::coroutines::detail::forced_unwind&) { + throw; + } catch (...) { + promise.set_exception(std::current_exception()); + throw; + } } promise.set_value(std::move(replies)); @@ -239,7 +258,15 @@ void RedisConnection::WriteLoop(asio::yield_context& yc) if (!m_Queues.GetResultOfQuery.empty()) { auto item (std::move(m_Queues.GetResultOfQuery.front())); m_Queues.GetResultOfQuery.pop(); - WriteOne(item.first, yc); + + try { + WriteOne(item.first, yc); + } catch (const boost::coroutines::detail::forced_unwind&) { + throw; + } catch (...) { + item.second.set_exception(std::current_exception()); + throw; + } m_Queues.ReplyPromises.emplace(std::move(item.second)); @@ -257,8 +284,15 @@ void RedisConnection::WriteLoop(asio::yield_context& yc) auto item (std::move(m_Queues.GetResultsOfQueries.front())); m_Queues.GetResultsOfQueries.pop(); - for (auto& query : item.first) { - WriteOne(query, yc); + try { + for (auto& query : item.first) { + WriteOne(query, yc); + } + } catch (const boost::coroutines::detail::forced_unwind&) { + throw; + } catch (...) { + item.second.set_exception(std::current_exception()); + throw; } m_Queues.RepliesPromises.emplace(std::move(item.second));