diff options
author | Kim Alvefur <zash@zash.se> | 2023-11-11 23:08:34 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2023-11-11 23:08:34 +0100 |
commit | 8e2ecac95b17cabc13a61a3d91ed99f350412f75 (patch) | |
tree | 80dffaf23f00b052128c0e24c9a202da0ff01da6 | |
parent | 1c4021b70feb60c101c39c499dda83729755aa3e (diff) | |
download | prosody-8e2ecac95b17cabc13a61a3d91ed99f350412f75.tar.gz prosody-8e2ecac95b17cabc13a61a3d91ed99f350412f75.zip |
net.http: Add simple connection pooling
This should speed up repeated requests to the same site by keeping their
connections around and sending more requests on them.
Sending multiple requests at the same time is not supported, instead a
request started while another to the same authority is in progress would
open a new one and the first one to complete would go back in the pool.
This could be investigated in the future.
Some http servers limit the number of requests per connection and this
is not tested and could cause one request to fail, but hopefully it will
close the connection and prevent it from being reused.
-rw-r--r-- | net/http.lua | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/net/http.lua b/net/http.lua index 07c7d41f..2685b491 100644 --- a/net/http.lua +++ b/net/http.lua @@ -51,10 +51,19 @@ local function log_if_failed(req, ret, ...) return ...; end -local function destroy_request(request) +local function destroy_request(request, force) local conn = request.conn; if conn then request.conn = nil; + local pool = request.http.pool; + if pool and not force then + local pool_id = request.scheme .. "://" .. request.authority; + if not pool[pool_id] then + pool[conn] = pool_id; + pool[pool_id] = conn; + return; + end + end conn:close() end end @@ -193,6 +202,13 @@ function listener.ondisconnect(conn, err) if request and request.conn then request:reader(nil, err or "closed"); end + if request and request.http.pool then + local pool = request.http.pool; + local pool_id = pool[conn]; + if pool_id then + pool[pool_id], pool[conn] = nil, nil; + end + end requests[conn] = nil; end @@ -296,6 +312,23 @@ local function request(self, u, ex, callback) end end + if self.pool then + local pool_id = req.scheme .. "://" .. req.authority; + local conn = self.pool[pool_id]; + if conn then + log("debug", "Re-using connection to %s from pool", req.host); + self.pool[pool_id] = nil; + self.pool[conn] = nil; + req.conn = conn; + requests[conn] = req; + self.events.fire_event("request", { http = self, request = req, url = u }); + listener.onconnect(conn); + return req; + else + log("debug", "Opening a new connection for this request"); + end + end + local http_service = basic_resolver.new(host, port_number, "tcp", { servername = req.host; use_dane = use_dane }); connect(http_service, listener, { sslctx = sslctx }, req); @@ -332,6 +365,10 @@ local function new(options) end or new; events = events.new(); }; + if options and options.connection_pooling then + -- util.cache in the future? + http.pool = {}; + end return http; end |