nghttpx: Don't reuse backend connection if it is not clean

This commit is contained in:
Tatsuhiro Tsujikawa 2015-07-22 21:41:16 +09:00
parent f3288092e8
commit 44cbc785fc
5 changed files with 25 additions and 39 deletions

View File

@ -1207,4 +1207,10 @@ void Downstream::add_request_headers_sum(size_t amount) {
request_headers_sum_ += amount; request_headers_sum_ += amount;
} }
bool Downstream::can_detach_downstream_connection() const {
return dconn_ && response_state_ == Downstream::MSG_COMPLETE &&
request_state_ == Downstream::MSG_COMPLETE && !upgraded_ &&
!response_connection_close_;
}
} // namespace shrpx } // namespace shrpx

View File

@ -332,6 +332,9 @@ public:
void attach_blocked_link(BlockedLink *l); void attach_blocked_link(BlockedLink *l);
BlockedLink *detach_blocked_link(); BlockedLink *detach_blocked_link();
// Returns true if downstream_connection can be detached and reused.
bool can_detach_downstream_connection() const;
enum { enum {
EVENT_ERROR = 0x1, EVENT_ERROR = 0x1,
EVENT_TIMEOUT = 0x2, EVENT_TIMEOUT = 0x2,

View File

@ -74,22 +74,13 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
return 0; return 0;
} }
downstream->set_request_state(Downstream::STREAM_CLOSED); if (downstream->can_detach_downstream_connection()) {
// Keep-alive
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { downstream->detach_downstream_connection();
// At this point, downstream response was read
if (!downstream->get_upgraded() &&
!downstream->get_response_connection_close()) {
// Keep-alive
downstream->detach_downstream_connection();
}
upstream->remove_downstream(downstream);
// downstream was deleted
return 0;
} }
downstream->set_request_state(Downstream::STREAM_CLOSED);
// At this point, downstream read may be paused. // At this point, downstream read may be paused.
// If shrpx_downstream::push_request_headers() failed, the // If shrpx_downstream::push_request_headers() failed, the
@ -915,10 +906,8 @@ int Http2Upstream::downstream_read(DownstreamConnection *dconn) {
} }
return downstream_error(dconn, Downstream::EVENT_ERROR); return downstream_error(dconn, Downstream::EVENT_ERROR);
} }
// Detach downstream connection early so that it could be reused
// without hitting server's request timeout. if (downstream->can_detach_downstream_connection()) {
if (downstream->get_response_state() == Downstream::MSG_COMPLETE &&
!downstream->get_response_connection_close()) {
// Keep-alive // Keep-alive
downstream->detach_downstream_connection(); downstream->detach_downstream_connection();
} }

View File

@ -540,7 +540,8 @@ int HttpsUpstream::on_write() {
// We need to postpone detachment until all data are sent so that // We need to postpone detachment until all data are sent so that
// we can notify nghttp2 library all data consumed. // we can notify nghttp2 library all data consumed.
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { if (downstream->get_response_state() == Downstream::MSG_COMPLETE) {
if (downstream->get_response_connection_close()) { if (downstream->get_response_connection_close() ||
downstream->get_request_state() != Downstream::MSG_COMPLETE) {
// Connection close // Connection close
downstream->pop_downstream_connection(); downstream->pop_downstream_connection();
// dconn was deleted // dconn was deleted
@ -607,10 +608,7 @@ int HttpsUpstream::downstream_read(DownstreamConnection *dconn) {
goto end; goto end;
} }
// Detach downstream connection early so that it could be reused if (downstream->can_detach_downstream_connection()) {
// without hitting server's request timeout.
if (downstream->get_response_state() == Downstream::MSG_COMPLETE &&
!downstream->get_response_connection_close()) {
// Keep-alive // Keep-alive
downstream->detach_downstream_connection(); downstream->detach_downstream_connection();
} }

View File

@ -109,20 +109,13 @@ void on_stream_close_callback(spdylay_session *session, int32_t stream_id,
return; return;
} }
downstream->set_request_state(Downstream::STREAM_CLOSED); if (downstream->can_detach_downstream_connection()) {
if (downstream->get_response_state() == Downstream::MSG_COMPLETE) { // Keep-alive
// At this point, downstream response was read downstream->detach_downstream_connection();
if (!downstream->get_upgraded() &&
!downstream->get_response_connection_close()) {
// Keep-alive
downstream->detach_downstream_connection();
}
upstream->remove_downstream(downstream);
// downstrea was deleted
return;
} }
downstream->set_request_state(Downstream::STREAM_CLOSED);
// At this point, downstream read may be paused. // At this point, downstream read may be paused.
// If shrpx_downstream::push_request_headers() failed, the // If shrpx_downstream::push_request_headers() failed, the
@ -589,10 +582,7 @@ int SpdyUpstream::downstream_read(DownstreamConnection *dconn) {
} }
return downstream_error(dconn, Downstream::EVENT_ERROR); return downstream_error(dconn, Downstream::EVENT_ERROR);
} }
// Detach downstream connection early so that it could be reused if (downstream->can_detach_downstream_connection()) {
// without hitting server's request timeout.
if (downstream->get_response_state() == Downstream::MSG_COMPLETE &&
!downstream->get_response_connection_close()) {
// Keep-alive // Keep-alive
downstream->detach_downstream_connection(); downstream->detach_downstream_connection();
} }