From 33e0dba013fa2282b7d48290c7df25d16d659f4e Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Mon, 25 Nov 2019 14:36:36 +0100 Subject: [PATCH] crimson/common/errorator.h: add handle_error() method. In contrast to `safe_then` it deals only with errors and, on return, leaves the value type `future` embodies unchanged. While being basically a specialization of `safe_then`, it's also a convenience method to squeeze boilerplate. Signed-off-by: Radoslaw Zarzynski --- src/crimson/common/errorator.h | 31 +++++++++++++++++++++++++++++++ src/crimson/osd/objclass.cc | 7 ++----- src/crimson/osd/osd_meta.cc | 8 ++------ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 17a95403fe6dc..2c6f80e33d704 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -544,6 +544,37 @@ private: template void then(Func&&) = delete; + template + auto handle_error(ErrorVisitorT&& errfunc) { + static_assert((... && std::is_invocable_v), + "provided Error Visitor is not exhaustive"); + using return_errorator_t = make_errorator_t< + errorator<>, + std::decay_t>...>; + using futurator_t = \ + typename return_errorator_t::template futurize<::seastar::future>; + return this->then_wrapped( + [ errfunc = std::forward(errfunc) + ] (auto&& future) mutable [[gnu::always_inline]] noexcept { + if (__builtin_expect(future.failed(), false)) { + return _safe_then_handle_errors( + std::move(future), std::forward(errfunc)); + } else { + return typename futurator_t::type{ std::move(future) }; + } + }); + } + template + auto handle_error(ErrorFuncHead&& error_func_head, + ErrorFuncTail&&... error_func_tail) { + static_assert(sizeof...(ErrorFuncTail) > 0); + return this->handle_error( + composer(std::forward(error_func_head), + std::forward(error_func_tail)...)); + } + private: // for ::crimson::do_for_each template diff --git a/src/crimson/osd/objclass.cc b/src/crimson/osd/objclass.cc index ef9336da1d7c3..da57b9c8a5cc6 100644 --- a/src/crimson/osd/objclass.cc +++ b/src/crimson/osd/objclass.cc @@ -25,11 +25,8 @@ static inline int execute_osd_op(cls_method_context_t hctx, OSDOp& op) // created for us by `seastar::async` in `::do_op_call()`. int ret = 0; using osd_op_errorator = crimson::osd::OpsExecuter::osd_op_errorator; - reinterpret_cast(hctx)->execute_osd_op(op).safe_then( - [] { - // TODO: handle it nicer with `::handle_error()` in errorator - return seastar::now(); - }, osd_op_errorator::all_same_way([&ret] (const std::error_code& err) { + reinterpret_cast(hctx)->execute_osd_op(op).handle_error( + osd_op_errorator::all_same_way([&ret] (const std::error_code& err) { assert(err.value() > 0); ret = -err.value(); return seastar::now(); diff --git a/src/crimson/osd/osd_meta.cc b/src/crimson/osd/osd_meta.cc index c608c8d351220..e7a1f06196442 100644 --- a/src/crimson/osd/osd_meta.cc +++ b/src/crimson/osd/osd_meta.cc @@ -24,12 +24,8 @@ seastar::future OSDMeta::load_map(epoch_t e) { return store->read(coll, osdmap_oid(e), 0, 0, - CEPH_OSD_OP_FLAG_FADVISE_WILLNEED).safe_then( - [] (auto&& bl) { - // TODO: introduce `::handle_error()` to errorated futures - // to avoid lambas like this one. - return bl; - }, crimson::ct_error::enoent::handle([e] { + CEPH_OSD_OP_FLAG_FADVISE_WILLNEED).handle_error( + crimson::ct_error::enoent::handle([e] { throw std::runtime_error(fmt::format("read gave enoent on {}", osdmap_oid(e))); })); -- 2.47.3