nghttpx: Retry next HTTP/2 backend address when connection cannot be made
This commit is contained in:
parent
bda352bf73
commit
b6708a4b87
|
@ -95,9 +95,7 @@ int Http2DownstreamConnection::attach_downstream(Downstream *downstream) {
|
||||||
DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
|
DCLOG(INFO, this) << "Attaching to DOWNSTREAM:" << downstream;
|
||||||
}
|
}
|
||||||
http2session_->add_downstream_connection(this);
|
http2session_->add_downstream_connection(this);
|
||||||
if (http2session_->get_state() == Http2Session::DISCONNECTED) {
|
http2session_->signal_write();
|
||||||
http2session_->signal_write();
|
|
||||||
}
|
|
||||||
|
|
||||||
downstream_ = downstream;
|
downstream_ = downstream;
|
||||||
downstream_->reset_downstream_rtimer();
|
downstream_->reset_downstream_rtimer();
|
||||||
|
|
|
@ -73,11 +73,9 @@ void connchk_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
SSLOG(INFO, http2session) << "ping timeout";
|
SSLOG(INFO, http2session) << "ping timeout";
|
||||||
}
|
}
|
||||||
http2session->disconnect();
|
|
||||||
|
|
||||||
if (http2session->get_num_dconns() == 0) {
|
delete http2session;
|
||||||
delete http2session;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
@ -95,10 +93,8 @@ void settings_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||||
http2session->stop_settings_timer();
|
http2session->stop_settings_timer();
|
||||||
SSLOG(INFO, http2session) << "SETTINGS timeout";
|
SSLOG(INFO, http2session) << "SETTINGS timeout";
|
||||||
if (http2session->terminate_session(NGHTTP2_SETTINGS_TIMEOUT) != 0) {
|
if (http2session->terminate_session(NGHTTP2_SETTINGS_TIMEOUT) != 0) {
|
||||||
http2session->disconnect();
|
delete http2session;
|
||||||
if (http2session->get_num_dconns() == 0) {
|
|
||||||
delete http2session;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
http2session->signal_write();
|
http2session->signal_write();
|
||||||
|
@ -114,11 +110,7 @@ void timeoutcb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||||
SSLOG(INFO, http2session) << "Timeout";
|
SSLOG(INFO, http2session) << "Timeout";
|
||||||
}
|
}
|
||||||
|
|
||||||
http2session->disconnect(http2session->get_state() ==
|
delete http2session;
|
||||||
Http2Session::CONNECTING);
|
|
||||||
if (http2session->get_num_dconns() == 0) {
|
|
||||||
delete http2session;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -129,20 +121,16 @@ void readcb(struct ev_loop *loop, ev_io *w, int revents) {
|
||||||
auto http2session = static_cast<Http2Session *>(conn->data);
|
auto http2session = static_cast<Http2Session *>(conn->data);
|
||||||
rv = http2session->do_read();
|
rv = http2session->do_read();
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
http2session->disconnect(http2session->should_hard_fail());
|
delete http2session;
|
||||||
if (http2session->get_num_dconns() == 0) {
|
|
||||||
delete http2session;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
http2session->connection_alive();
|
http2session->connection_alive();
|
||||||
|
|
||||||
rv = http2session->do_write();
|
rv = http2session->do_write();
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
http2session->disconnect(http2session->should_hard_fail());
|
delete http2session;
|
||||||
if (http2session->get_num_dconns() == 0) {
|
|
||||||
delete http2session;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,10 +143,8 @@ void writecb(struct ev_loop *loop, ev_io *w, int revents) {
|
||||||
auto http2session = static_cast<Http2Session *>(conn->data);
|
auto http2session = static_cast<Http2Session *>(conn->data);
|
||||||
rv = http2session->do_write();
|
rv = http2session->do_write();
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
http2session->disconnect(http2session->should_hard_fail());
|
delete http2session;
|
||||||
if (http2session->get_num_dconns() == 0) {
|
|
||||||
delete http2session;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
http2session->reset_connection_check_timer_if_not_checking();
|
http2session->reset_connection_check_timer_if_not_checking();
|
||||||
|
@ -173,9 +159,9 @@ void initiate_connection_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
||||||
if (LOG_ENABLED(INFO)) {
|
if (LOG_ENABLED(INFO)) {
|
||||||
SSLOG(INFO, http2session) << "Could not initiate backend connection";
|
SSLOG(INFO, http2session) << "Could not initiate backend connection";
|
||||||
}
|
}
|
||||||
http2session->disconnect(true);
|
|
||||||
assert(http2session->get_num_dconns() == 0);
|
|
||||||
delete http2session;
|
delete http2session;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,9 +209,8 @@ Http2Session::Http2Session(struct ev_loop *loop, SSL_CTX *ssl_ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
Http2Session::~Http2Session() {
|
Http2Session::~Http2Session() {
|
||||||
disconnect(true);
|
exclude_from_scheduling();
|
||||||
|
disconnect(should_hard_fail());
|
||||||
remove_from_freelist();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Http2Session::disconnect(bool hard) {
|
int Http2Session::disconnect(bool hard) {
|
||||||
|
@ -1940,9 +1925,11 @@ bool Http2Session::should_hard_fail() const {
|
||||||
switch (state_) {
|
switch (state_) {
|
||||||
case PROXY_CONNECTING:
|
case PROXY_CONNECTING:
|
||||||
case PROXY_FAILED:
|
case PROXY_FAILED:
|
||||||
case CONNECTING:
|
|
||||||
case CONNECT_FAILING:
|
|
||||||
return true;
|
return true;
|
||||||
|
case DISCONNECTED: {
|
||||||
|
const auto &proxy = get_config()->downstream_http_proxy;
|
||||||
|
return !proxy.host.empty();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2112,9 +2099,16 @@ void Http2Session::remove_from_freelist() {
|
||||||
}
|
}
|
||||||
addr_->http2_extra_freelist.remove(this);
|
addr_->http2_extra_freelist.remove(this);
|
||||||
break;
|
break;
|
||||||
|
case FREELIST_ZONE_GONE:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
freelist_zone_ = FREELIST_ZONE_NONE;
|
freelist_zone_ = FREELIST_ZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Http2Session::exclude_from_scheduling() {
|
||||||
|
remove_from_freelist();
|
||||||
|
freelist_zone_ = FREELIST_ZONE_GONE;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -64,7 +64,10 @@ enum FreelistZone {
|
||||||
FREELIST_ZONE_AVAIL,
|
FREELIST_ZONE_AVAIL,
|
||||||
// Http2Session object is linked in address scope
|
// Http2Session object is linked in address scope
|
||||||
// http2_extra_freelist.
|
// http2_extra_freelist.
|
||||||
FREELIST_ZONE_EXTRA
|
FREELIST_ZONE_EXTRA,
|
||||||
|
// Http2Session object is about to be deleted, and it does not
|
||||||
|
// belong to any linked list.
|
||||||
|
FREELIST_ZONE_GONE
|
||||||
};
|
};
|
||||||
|
|
||||||
class Http2Session {
|
class Http2Session {
|
||||||
|
@ -180,6 +183,10 @@ public:
|
||||||
// linked from any freelist, this function does nothing.
|
// linked from any freelist, this function does nothing.
|
||||||
void remove_from_freelist();
|
void remove_from_freelist();
|
||||||
|
|
||||||
|
// Removes this object form any freelist, and marks this object as
|
||||||
|
// not schedulable.
|
||||||
|
void exclude_from_scheduling();
|
||||||
|
|
||||||
// Returns true if the maximum concurrency is reached. In other
|
// Returns true if the maximum concurrency is reached. In other
|
||||||
// words, the number of currently participated streams in this
|
// words, the number of currently participated streams in this
|
||||||
// session is equal or greater than the max concurrent streams limit
|
// session is equal or greater than the max concurrent streams limit
|
||||||
|
|
|
@ -1759,6 +1759,11 @@ int Http2Upstream::on_downstream_reset(bool no_retry) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = downstream->push_request_headers();
|
||||||
|
if (rv != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -1197,6 +1197,11 @@ int HttpsUpstream::on_downstream_reset(bool no_retry) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = downstream_->push_request_headers();
|
||||||
|
if (rv != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -1269,6 +1269,11 @@ int SpdyUpstream::on_downstream_reset(bool no_retry) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = downstream->push_request_headers();
|
||||||
|
if (rv != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
Loading…
Reference in New Issue