Skip to content

Commit

Permalink
http/client: Coroutinize client::do_make_request (con-less overload)
Browse files Browse the repository at this point in the history
It makes some non-trivial decisions on whether or to retry the request
in the catch block, so the conversion is a bit hairy.

Signed-off-by: Pavel Emelyanov <[email protected]>
  • Loading branch information
xemul committed Sep 12, 2024
1 parent 539fa2a commit 3231966
Showing 1 changed file with 12 additions and 12 deletions.
24 changes: 12 additions & 12 deletions src/http/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,31 +307,31 @@ future<> client::make_request(request req, reply_handler handle, abort_source& a
}

future<> client::do_make_request(request req, reply_handler handle, abort_source* as, std::optional<reply::status_type> expected) {
return do_with(std::move(req), std::move(handle), [this, as, expected] (request& req, reply_handler& handle) mutable {
return with_connection([this, &req, &handle, as, expected] (connection& con) {
return do_make_request(con, req, handle, as, expected);
}, as).handle_exception_type([this, &req, &handle, as, expected] (const std::system_error& ex) {
try {
co_return co_await with_connection(coroutine::lambda([this, &req, &handle, as, expected] (connection& con) -> future<> {
co_await do_make_request(con, req, handle, as, expected);
}), as);
} catch (const std::system_error& ex) {
if (as && as->abort_requested()) {
return make_exception_future<>(as->abort_requested_exception_ptr());
std::rethrow_exception(as->abort_requested_exception_ptr());
}

if (!_retry) {
return make_exception_future<>(ex);
throw;
}

auto code = ex.code().value();
if ((code != EPIPE) && (code != ECONNABORTED)) {
return make_exception_future<>(ex);
throw;
}
}

// The 'con' connection may not yet be freed, so the total connection
// count still account for it and with_new_connection() may temporarily
// break the limit. That's OK, the 'con' will be closed really soon
return with_new_connection([this, &req, &handle, as, expected] (connection& con) {
return do_make_request(con, req, handle, as, expected);
}, as);
});
});
co_await with_new_connection(coroutine::lambda([this, &req, &handle, as, expected] (connection& con) -> future<> {
co_await do_make_request(con, req, handle, as, expected);
}), as);
}

future<> client::do_make_request(connection& con, request& req, reply_handler& handle, abort_source* as, std::optional<reply::status_type> expected) {
Expand Down

0 comments on commit 3231966

Please sign in to comment.