diff --git a/src/h2load.cc b/src/h2load.cc index e7840d25..aa6f5de4 100644 --- a/src/h2load.cc +++ b/src/h2load.cc @@ -269,9 +269,7 @@ void conn_timeout_cb(EV_P_ ev_timer *w, int revents) { namespace { bool check_stop_client_request_timeout(Client *client, ev_timer *w) { - auto nreq = client->req_todo - client->req_started; - - if (nreq == 0 || + if (client->req_left == 0 || client->streams.size() >= client->session->max_concurrent_streams()) { // no more requests to make, stop timer ev_timer_stop(client->worker->loop, w); @@ -330,6 +328,8 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo) reqidx(0), state(CLIENT_IDLE), req_todo(req_todo), + req_left(req_todo), + req_inflight(0), req_started(0), req_done(0), id(id), @@ -467,16 +467,13 @@ int Client::try_again_or_fail() { if (new_connection_requested) { new_connection_requested = false; - if (req_started < req_todo) { + if (req_left) { // At the moment, we don't have a facility to re-start request // already in in-flight. Make them fail. - auto req_abandoned = req_started - req_done; + worker->stats.req_failed += req_inflight; + worker->stats.req_error += req_inflight; - worker->stats.req_failed += req_abandoned; - worker->stats.req_error += req_abandoned; - worker->stats.req_done += req_abandoned; - - req_done = req_started; + req_inflight = 0; // Keep using current address if (connect() == 0) { @@ -528,16 +525,18 @@ void Client::disconnect() { } int Client::submit_request() { - ++worker->stats.req_started; if (session->submit_request() != 0) { return -1; } + ++worker->stats.req_started; + --req_left; ++req_started; + ++req_inflight; // if an active timeout is set and this is the last request to be submitted // on this connection, start the active timeout. - if (worker->config->conn_active_timeout > 0. && req_started >= req_todo) { + if (worker->config->conn_active_timeout > 0. && req_left == 0) { ev_timer_start(worker->loop, &conn_active_watcher); } @@ -551,34 +550,29 @@ void Client::process_timedout_streams() { } } - auto req_timed_out = req_todo - req_done; - worker->stats.req_timedout += req_timed_out; + worker->stats.req_timedout += req_inflight; process_abandoned_streams(); } void Client::process_abandoned_streams() { - auto req_abandoned = req_todo - req_done; + auto req_abandoned = req_inflight + req_left; worker->stats.req_failed += req_abandoned; worker->stats.req_error += req_abandoned; - worker->stats.req_done += req_abandoned; - req_done = req_todo; + req_inflight = 0; + req_left = 0; } void Client::process_request_failure() { - auto req_abandoned = req_todo - req_started; + worker->stats.req_failed += req_left; + worker->stats.req_error += req_left; - worker->stats.req_failed += req_abandoned; - worker->stats.req_error += req_abandoned; - worker->stats.req_done += req_abandoned; + req_left = 0; - req_done += req_abandoned; - - if (req_done == req_todo) { + if (req_inflight == 0) { terminate_session(); - return; } } @@ -711,6 +705,9 @@ void Client::on_status_code(int32_t stream_id, uint16_t status) { } void Client::on_stream_close(int32_t stream_id, bool success, bool final) { + ++req_done; + --req_inflight; + auto req_stat = get_req_stat(stream_id); if (!req_stat) { return; @@ -741,22 +738,18 @@ void Client::on_stream_close(int32_t stream_id, bool success, bool final) { } ++worker->stats.req_done; - ++req_done; worker->report_progress(); streams.erase(stream_id); - if (req_done == req_todo) { + if (req_left == 0 && req_inflight == 0) { terminate_session(); return; } - if (!config.timing_script && !final) { - if (req_started < req_todo) { - if (submit_request() != 0) { - process_request_failure(); - } - return; - } + if (!config.timing_script && !final && req_left > 0 && + submit_request() != 0) { + process_request_failure(); + return; } } @@ -871,8 +864,7 @@ int Client::connection_made() { record_connect_time(); if (!config.timing_script) { - auto nreq = - std::min(req_todo - req_started, session->max_concurrent_streams()); + auto nreq = std::min(req_left, session->max_concurrent_streams()); for (; nreq > 0; --nreq) { if (submit_request() != 0) { process_request_failure(); diff --git a/src/h2load.h b/src/h2load.h index 0b84d2a6..db50472d 100644 --- a/src/h2load.h +++ b/src/h2load.h @@ -292,6 +292,11 @@ struct Client { ClientState state; // The number of requests this client has to issue. size_t req_todo; + // The number of requests left to issue + size_t req_left; + // The number of requests currently have started, but not abandoned + // or finished. + size_t req_inflight; // The number of requests this client has issued so far. size_t req_started; // The number of requests this client has done so far. diff --git a/src/h2load_http1_session.cc b/src/h2load_http1_session.cc index 6080e1fb..645e11ab 100644 --- a/src/h2load_http1_session.cc +++ b/src/h2load_http1_session.cc @@ -100,7 +100,7 @@ int htp_msg_completecb(http_parser *htp) { http_parser_pause(htp, 1); // Connection is going down. If we have still request to do, // create new connection and keep on doing the job. - if (client->req_started < client->req_todo) { + if (client->req_left) { client->try_new_connection(); }