]> hydra-www.ietfng.org Git - acmetensortoys-esp-lua_core/commitdiff
New fifosock implementation
authorNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sun, 12 Aug 2018 10:22:46 +0000 (11:22 +0100)
committerNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sun, 12 Aug 2018 10:33:41 +0000 (11:33 +0100)
Two-layer approach borrowing from TerryE's example telnet server

net/fifosock.lua

index dee7f3a099b17b4ba248af57fea22324b2829bed..87cf26c7f3a7e5dd64daaa3d5c413a4b4b281b35 100644 (file)
@@ -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