aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-08-16 12:34:52 +0200
committerKim Alvefur <zash@zash.se>2021-08-16 12:34:52 +0200
commitd06ae1629513e0a8ab8c1a24566226dddc93e8e1 (patch)
tree1734b65d5c33a62a267fdf8394066b89fa732570 /net
parentb686dda4afa8f519830997dc88386a37e371d47e (diff)
downloadprosody-d06ae1629513e0a8ab8c1a24566226dddc93e8e1.tar.gz
prosody-d06ae1629513e0a8ab8c1a24566226dddc93e8e1.zip
net.server: Add a predrain callaback just before writes
Allows sneaking in things in the write buffer just before it's sent to the network stack. For example ack requests, compression flushes or other things that make sense to send after stanzas or other things. This ensures any additional trailing data sent is included in the same write, and possibly the same TCP packet. Other methods used such as timers or nextTick might not have the same effect as it depends on scheduling.
Diffstat (limited to 'net')
-rw-r--r--net/server_epoll.lua1
-rw-r--r--net/server_event.lua5
-rw-r--r--net/server_select.lua5
3 files changed, 11 insertions, 0 deletions
diff --git a/net/server_epoll.lua b/net/server_epoll.lua
index b737ee59..60ecb687 100644
--- a/net/server_epoll.lua
+++ b/net/server_epoll.lua
@@ -472,6 +472,7 @@ end
function interface:onwritable()
self:onconnect();
if not self.conn then return; end -- could have been closed in onconnect
+ self:on("predrain");
local buffer = self.writebuffer;
local data = buffer or "";
if type(buffer) == "table" then
diff --git a/net/server_event.lua b/net/server_event.lua
index f7e1f448..139c7e5f 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -449,6 +449,7 @@ function interface_mt:setlistener(listener, data)
self.onstatus = listener.onstatus;
self.ondetach = listener.ondetach;
self.onattach = listener.onattach;
+ self.onpredrain = listener.onpredrain;
self.ondrain = listener.ondrain;
self:onattach(data);
end
@@ -464,6 +465,8 @@ function interface_mt:ontimeout()
end
function interface_mt:onreadtimeout()
end
+function interface_mt:onpredrain()
+end
function interface_mt:ondrain()
end
function interface_mt:ondetach()
@@ -490,6 +493,7 @@ local function handleclient( client, ip, port, server, pattern, listener, sslctx
onincoming = listener.onincoming; -- will be called when client sends data
ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs
onreadtimeout = listener.onreadtimeout; -- called when socket inactivity timeout occurs
+ onpredrain = listener.onpredrain; -- called before writes
ondrain = listener.ondrain; -- called when writebuffer is empty
ondetach = listener.ondetach; -- called when disassociating this listener from this connection
onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS)
@@ -540,6 +544,7 @@ local function handleclient( client, ip, port, server, pattern, listener, sslctx
interface.eventwritetimeout = false
end
end
+ interface:onpredrain();
interface.writebuffer = { t_concat(interface.writebuffer) }
local succ, err, byte = interface.conn:send( interface.writebuffer[1], 1, interface.writebufferlen )
--vdebug( "write data:", interface.writebuffer, "error:", err, "part:", byte )
diff --git a/net/server_select.lua b/net/server_select.lua
index 09c1c027..eea850ce 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -294,6 +294,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
local dispatch = listeners.onincoming
local status = listeners.onstatus
local disconnect = listeners.ondisconnect
+ local predrain = listeners.onpredrain
local drain = listeners.ondrain
local onreadtimeout = listeners.onreadtimeout;
local detach = listeners.ondetach
@@ -338,6 +339,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
dispatch = listeners.onincoming
disconnect = listeners.ondisconnect
status = listeners.onstatus
+ predrain = listeners.onpredrain
drain = listeners.ondrain
handler.onreadtimeout = listeners.onreadtimeout
detach = listeners.ondetach
@@ -552,6 +554,9 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
listeners.onconnect(handler);
end
end
+ if predrain then
+ predrain(handler);
+ end
buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
succ, err, byte = send( socket, buffer, 1, bufferlen )
count = ( succ or byte or 0 ) * STAT_UNIT