HTTP: adjust request-connection assignment.

Prefer existing, idle connections to creating new connections,
even when below the max-connection limit. Gives much better re-use
and pipeline-ing, and hence reduced setup time/trips.
This commit is contained in:
James Turner 2013-09-28 14:03:39 +01:00
parent add14dd27c
commit 483659c319

View File

@ -696,10 +696,7 @@ private:
void responseComplete()
{
// SG_LOG(SG_IO, SG_INFO, "*** responseComplete:" << activeRequest->url());
activeRequest->responseComplete();
client->requestFinished(this);
Request_ptr completedRequest = activeRequest;
if (contentDeflate) {
inflateEnd(&zlib);
}
@ -723,6 +720,13 @@ private:
if (state != STATE_CLOSED) {
state = sentRequests.empty() ? STATE_IDLE : STATE_WAITING_FOR_RESPONSE;
}
// notify request after we change state, so this connection is idle
// if completion triggers other requests (which is likely)
// SG_LOG(SG_IO, SG_INFO, "*** responseComplete:" << activeRequest->url());
completedRequest->responseComplete();
client->requestFinished(this);
setTerminator("\r\n");
}
@ -844,13 +848,13 @@ void Client::makeRequest(const Request_ptr& r)
ss << host << "-" << port;
string connectionId = ss.str();
bool havePending = !d->pendingRequests.empty();
bool atConnectionsLimit = d->connections.size() >= d->maxConnections;
ConnectionDict::iterator consEnd = d->connections.end();
// assign request to an existing Connection.
// various options exist here, examined in order
if (d->connections.size() >= d->maxConnections) {
ConnectionDict::iterator it = d->connections.find(connectionId);
if (it == consEnd) {
if (atConnectionsLimit && (it == consEnd)) {
// maximum number of connections active, queue this request
// when a connection goes inactive, we'll start this one
d->pendingRequests.push_back(r);
@ -872,15 +876,15 @@ void Client::makeRequest(const Request_ptr& r)
}
}
if (!con) {
// we have at least one connection to the host, but they are
// all active - we need to pick one to queue the request on.
// we use random but round-robin would also work.
if (!con && atConnectionsLimit) {
// all current connections are busy (active), and we don't
// have free connections to allocate, so let's assign to
// an existing one randomly. Ideally we'd used whichever one will
// complete first but we don't have that info.
int index = rand() % count;
for (it = d->connections.find(connectionId); index > 0; --index) { ; }
con = it->second;
}
} // of at max connections limit
// allocate a new connection object
if (!con) {