Don't terminate HTTP requests with timeouts if response is already available in the socket
parent
b7b2adfa32
commit
390239c51b
|
@ -65,7 +65,7 @@ struct http_co_t
|
||||||
void next_request();
|
void next_request();
|
||||||
void handle_events();
|
void handle_events();
|
||||||
void handle_connect_result();
|
void handle_connect_result();
|
||||||
void submit_read();
|
void submit_read(bool check_timeout);
|
||||||
void submit_send();
|
void submit_send();
|
||||||
bool handle_read();
|
bool handle_read();
|
||||||
void post_message(int type, const std::string & msg);
|
void post_message(int type, const std::string & msg);
|
||||||
|
@ -167,10 +167,19 @@ void http_co_t::send_request(const std::string & host, const std::string & reque
|
||||||
timeout_id = tfd->set_timer(request_timeout, false, [this](int timer_id)
|
timeout_id = tfd->set_timer(request_timeout, false, [this](int timer_id)
|
||||||
{
|
{
|
||||||
stackin();
|
stackin();
|
||||||
|
if (state == HTTP_CO_REQUEST_SENT)
|
||||||
|
{
|
||||||
|
// In case of high CPU load, we may not handle etcd responses in time
|
||||||
|
// For this case, first check the socket and only then terminate request with the timeout
|
||||||
|
submit_read(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
close_connection();
|
close_connection();
|
||||||
parsed = { .error = "HTTP request timed out" };
|
parsed = { .error = "HTTP request timed out" };
|
||||||
run_cb_and_clear();
|
run_cb_and_clear();
|
||||||
next_request();
|
next_request();
|
||||||
|
}
|
||||||
stackout();
|
stackout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -328,7 +337,7 @@ void http_co_t::handle_events()
|
||||||
epoll_events &= ~EPOLLOUT;
|
epoll_events &= ~EPOLLOUT;
|
||||||
if (epoll_events & EPOLLIN)
|
if (epoll_events & EPOLLIN)
|
||||||
{
|
{
|
||||||
submit_read();
|
submit_read(false);
|
||||||
}
|
}
|
||||||
else if (epoll_events & (EPOLLRDHUP|EPOLLERR))
|
else if (epoll_events & (EPOLLRDHUP|EPOLLERR))
|
||||||
{
|
{
|
||||||
|
@ -418,10 +427,11 @@ again:
|
||||||
stackout();
|
stackout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_co_t::submit_read()
|
void http_co_t::submit_read(bool check_timeout)
|
||||||
{
|
{
|
||||||
stackin();
|
stackin();
|
||||||
int res;
|
int res;
|
||||||
|
again:
|
||||||
if (rbuf.size() != READ_BUFFER_SIZE)
|
if (rbuf.size() != READ_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
rbuf.resize(READ_BUFFER_SIZE);
|
rbuf.resize(READ_BUFFER_SIZE);
|
||||||
|
@ -435,9 +445,25 @@ void http_co_t::submit_read()
|
||||||
res = -errno;
|
res = -errno;
|
||||||
}
|
}
|
||||||
if (res == -EAGAIN || res == -EINTR)
|
if (res == -EAGAIN || res == -EINTR)
|
||||||
|
{
|
||||||
|
if (check_timeout)
|
||||||
|
{
|
||||||
|
if (res == -EINTR)
|
||||||
|
goto again;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Timeout happened and there is no data to read
|
||||||
|
close_connection();
|
||||||
|
parsed = { .error = "HTTP request timed out" };
|
||||||
|
run_cb_and_clear();
|
||||||
|
next_request();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
epoll_events = epoll_events & ~EPOLLIN;
|
epoll_events = epoll_events & ~EPOLLIN;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (res <= 0)
|
else if (res <= 0)
|
||||||
{
|
{
|
||||||
// < 0 means error, 0 means EOF
|
// < 0 means error, 0 means EOF
|
||||||
|
|
Loading…
Reference in New Issue