The send_helper::operator() waits for two futures to resolve -- the
sending one and receiving-the-response one. The latter future result
is then propagated back to caller.
However, the former future may also resolve into exception sometimes,
and this exception should be correctly short-circuited.
Nowadays this doesn't really happen, because .send() only resolved
into exception if it noticed error on entry and the helper didn't let
this happen by checking the error early itself. After 8c82d889 (rpc:
Send messages instantly) exceptions started popping up asynchronously.
tests: scylla.unit(dev), rpc(dev)
Signed-off-by: Pavel Emelyanov <
xe...@scylladb.com>
---
include/seastar/rpc/rpc_impl.hh | 1 +
tests/unit/rpc_test.cc | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/include/seastar/rpc/rpc_impl.hh b/include/seastar/rpc/rpc_impl.hh
index e74e2e2d..2a1509d1 100644
--- a/include/seastar/rpc/rpc_impl.hh
+++ b/include/seastar/rpc/rpc_impl.hh
@@ -478,6 +478,7 @@ auto send_helper(MsgType xt, signature<Ret (InArgs...)> xsig) {
// prepare reply handler, if return type is now_wait_type this does nothing, since no reply will be sent
using wait = wait_signature_t<Ret>;
return when_all(dst.send(std::move(data), timeout, cancel), wait_for_reply<Serializer>(wait(), timeout, cancel, dst, msg_id, sig)).then([] (auto r) {
+ std::get<0>(r).ignore_ready_future();
return std::move(std::get<1>(r)); // return future of wait_for_reply
});
}
diff --git a/tests/unit/rpc_test.cc b/tests/unit/rpc_test.cc
index 134d7e5c..69e6d597 100644
--- a/tests/unit/rpc_test.cc
+++ b/tests/unit/rpc_test.cc
@@ -365,7 +365,12 @@ SEASTAR_TEST_CASE(test_rpc_connect_abort) {
test_rpc_proto::client c1(env.proto(), {}, env.make_socket(), ipv4_addr());
env.register_handler(1, []() { return make_ready_future<>(); }).get();
auto f = env.proto().make_client<void ()>(1);
+ auto fut = f(c1);
c1.stop().get0();
+ try {
+ fut.get0();
+ BOOST_REQUIRE(false);
+ } catch (...) {}
try {
f(c1).get0();
BOOST_REQUIRE(false);
--
2.20.1