h2load: Explicitly count the number of requests left and inflight
This commit is contained in:
parent
712b08e8ed
commit
7e6eb7e02a
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue