From 3dd198413b04ca530af9b8fe5b44cfd511646dd0 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Sun, 12 Aug 2018 11:22:46 +0100 Subject: [PATCH] New fifosock implementation Two-layer approach borrowing from TerryE's example telnet server --- net/fifosock.lua | 54 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/net/fifosock.lua b/net/fifosock.lua index dee7f3a..87cf26c 100644 --- a/net/fifosock.lua +++ b/net/fifosock.lua @@ -1,10 +1,54 @@ --- Wrap a fifo around a socket's send -return function(fifo,sock) - local function dosend(s) sock:send(s) end - sock:on("sent", function() fifo:dequeue(dosend) end) +-- Wrap a two-staged fifo around a socket's send, borrowing TerryE's +-- scheme from NodeMCU's lua_examples/telnet/telnet.lua . + +local BIGTHRESH = 256 -- how big is a "big" string? +local SPLITSLOP = 16 -- any slop in the big question? +local FSMALLLIM = 32 -- maximum number of small strings held + +local concat = table.concat +local insert = table.insert + +local fifo = (require "fifo")() + +return function(sock) + local ssend = function(s) sock:send(s) end + local fsmall, lsmall, fbig = {}, 0, fifo() + + -- Move fsmall to fbig; might send if fbig empty + local function promote() + if #fsmall == 0 then return end + local str = concat(fsmall) + fsmall, lsmall = {}, 0 + fbig:queue(str, ssend) + end + + local function sendnext() + if not fbig:dequeue(ssend) then promote() end + end + + sock:on("sent", sendnext) return function(s) + -- don't sweat the petty things if s == nil or s == "" then return end - fifo:queue(s,dosend) + + -- small fifo would overfill? promote it + if lsmall + #s > BIGTHRESH or #fsmall >= FSMALLLIM then promote() end + + -- big string? chunk and queue big components immediately + -- behind any promotion that just took place + while #s > BIGTHRESH + SPLITSLOP do + local pfx + pfx, s = s:sub(1,256), s:sub(257) + fbig:queue(pfx, ssend) + end + + -- Big string? queue + if #s > BIGTHRESH then fbig:queue(s, ssend) + -- small and empty line; start txing now. (no corking) + elseif fbig._go and lsmall == 0 then fbig:queue(s, ssend) + -- small and queue already moving + else insert(fsmall, s) ; lsmall = lsmall + #s + end end end -- 2.50.1