Commit a1be6b64 authored by knowledge4igor's avatar knowledge4igor

Fix connection OnDone execution: problem was introduced in PR #374

parent 1ec54cd8
...@@ -425,10 +425,12 @@ Connection::handleResponsePacket(const char* buffer, size_t totalBytes) { ...@@ -425,10 +425,12 @@ Connection::handleResponsePacket(const char* buffer, size_t totalBytes) {
} }
requestEntry->resolve(std::move(parser.response)); requestEntry->resolve(std::move(parser.response));
if (requestEntry->onDone) auto onDone = requestEntry->onDone;
requestEntry->onDone();
requestEntry.reset(nullptr); requestEntry.reset(nullptr);
if (onDone)
onDone();
} }
} else { } else {
// TODO: Do more specific error // TODO: Do more specific error
...@@ -444,11 +446,14 @@ Connection::handleError(const char* error) { ...@@ -444,11 +446,14 @@ Connection::handleError(const char* error) {
timerPool_.releaseTimer(requestEntry->timer); timerPool_.releaseTimer(requestEntry->timer);
} }
auto onDone = requestEntry->onDone;
requestEntry->reject(Error(error)); requestEntry->reject(Error(error));
if (requestEntry->onDone)
requestEntry->onDone();
requestEntry.reset(nullptr); requestEntry.reset(nullptr);
if (onDone)
onDone();
} }
} }
...@@ -457,12 +462,15 @@ Connection::handleTimeout() { ...@@ -457,12 +462,15 @@ Connection::handleTimeout() {
if (requestEntry) { if (requestEntry) {
timerPool_.releaseTimer(requestEntry->timer); timerPool_.releaseTimer(requestEntry->timer);
if (requestEntry->onDone) auto onDone = requestEntry->onDone;
requestEntry->onDone();
/* @API: create a TimeoutException */ /* @API: create a TimeoutException */
requestEntry->reject(std::runtime_error("Timeout")); requestEntry->reject(std::runtime_error("Timeout"));
requestEntry.reset(nullptr); requestEntry.reset(nullptr);
if (onDone)
onDone();
} }
} }
......
...@@ -190,3 +190,46 @@ TEST(http_client_test, timeout_reject) ...@@ -190,3 +190,46 @@ TEST(http_client_test, timeout_reject)
ASSERT_TRUE(is_reject); ASSERT_TRUE(is_reject);
} }
TEST(http_client_test, one_client_with_multiple_requests_and_one_connection_per_host)
{
const std::string address = "localhost:9104";
Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
auto server_opts = Http::Endpoint::options().flags(flags);
server.init(server_opts);
server.setHandler(Http::make_handler<HelloHandler>());
server.serveThreaded();
Http::Client client;
auto opts = Http::Client::options().maxConnectionsPerHost(1).threads(2);
client.init(opts);
std::vector<Async::Promise<Http::Response>> responses;
const int RESPONSE_SIZE = 6;
std::atomic<int> response_counter = 0;
auto rb = client.get(address);
for (int i = 0; i < RESPONSE_SIZE; ++i)
{
auto response = rb.send();
response.then([&](Http::Response rsp)
{
if (rsp.code() == Http::Code::Ok)
++response_counter;
},
Async::IgnoreException);
responses.push_back(std::move(response));
}
auto sync = Async::whenAll(responses.begin(), responses.end());
Async::Barrier<std::vector<Http::Response>> barrier(sync);
barrier.wait_for(std::chrono::seconds(5));
server.shutdown();
client.shutdown();
ASSERT_TRUE(response_counter == RESPONSE_SIZE);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment