# HG changeset patch # User Kim Alvefur # Date 1629110092 -7200 # Node ID dcf38ac6a38c88d314c851f477ccca156d94df35 # Parent b92f2abe0bda17b481f9d675e04331de16efffd7 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. diff -r b92f2abe0bda -r dcf38ac6a38c net/server_epoll.lua --- a/net/server_epoll.lua Mon Aug 16 11:37:51 2021 +0200 +++ b/net/server_epoll.lua Mon Aug 16 12:34:52 2021 +0200 @@ -472,6 +472,7 @@ 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 -r b92f2abe0bda -r dcf38ac6a38c net/server_event.lua --- a/net/server_event.lua Mon Aug 16 11:37:51 2021 +0200 +++ b/net/server_event.lua Mon Aug 16 12:34:52 2021 +0200 @@ -449,6 +449,7 @@ 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 @@ end function interface_mt:onreadtimeout() end +function interface_mt:onpredrain() +end function interface_mt:ondrain() end function interface_mt:ondetach() @@ -490,6 +493,7 @@ 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 @@ 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 -r b92f2abe0bda -r dcf38ac6a38c net/server_select.lua --- a/net/server_select.lua Mon Aug 16 11:37:51 2021 +0200 +++ b/net/server_select.lua Mon Aug 16 12:34:52 2021 +0200 @@ -294,6 +294,7 @@ 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 @@ 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 @@ 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