From 9733a9b5a5ba69fd1228c8d8dae10a551ba67df4 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Fri, 22 Feb 2019 23:26:57 +0000 Subject: [PATCH] Remove fifo; has been pushed upstream Keep fifotest and fifodiag, tho', which may be useful and were inappropriate to send upstream. --- README.rst | 6 +- fifo/fifo.lua | 44 -------------- host/pushinit.sh | 11 +++- net/fifosock.lua | 118 ------------------------------------ {fifo => old}/fifo-diag.lua | 0 {test => old}/fifotest.lua | 0 telnetd/telnetd-diag.lua | 7 ++- telnetd/telnetd.lua | 3 +- test/fifosocktest.lua | 110 --------------------------------- 9 files changed, 18 insertions(+), 281 deletions(-) delete mode 100644 fifo/fifo.lua delete mode 100644 net/fifosock.lua rename {fifo => old}/fifo-diag.lua (100%) rename {test => old}/fifotest.lua (100%) delete mode 100644 test/fifosocktest.lua diff --git a/README.rst b/README.rst index 29d16af..e92c2b0 100644 --- a/README.rst +++ b/README.rst @@ -44,9 +44,9 @@ Generic Utilities Networking Utilities -------------------- -* ``util/fifosock.lua`` -- wraps around the nodemcu/ESP8266 socket sending - side to provide FIFO execution of ``:send`` calls. Absent such a - facility, each ``:send`` is run asynchronously as its own task. +* The ``fifosock`` module that used to be here has been merged into NodeMCU! + See ``lua_modules/fifo/fifosock.lua`` in its repository or perhaps skip to + https://nodemcu.readthedocs.io/en/dev/lua-modules/fifosock/ . Networking Framework -------------------- diff --git a/fifo/fifo.lua b/fifo/fifo.lua deleted file mode 100644 index 6c64e69..0000000 --- a/fifo/fifo.lua +++ /dev/null @@ -1,44 +0,0 @@ --- Remove an element and pass it to k; if that returns a value, leave that --- pending at the top of the fifo. Thus, we can get events that do multiple --- things. --- --- If k returns nil, the fifo will be advanced. Moreover, k may return a --- second result, a boolean, which indicates whether or not this dequeue --- "counts" as one; this is useful for "phantom" elements in the fifo, such as --- (placeholders for) callbacks to observers, that cannot otherwise act as --- ordinary fifo elements do. --- --- k is also given a second argument, a boolean indicating that this is the --- last element in the queue. --- --- If the queue is empty, do not invoke k but flag it to enable immediate --- execution at the next call to queue. --- --- Returns 'true' if the queue contained at least one non-phantom entry, --- 'false' otherwise. -local function dequeue(q,k) - if #q > 0 - then - local new, again = k(q[1], #q == 1) - if new == nil - then table.remove(q,1) - if again then return dequeue(q, k) end -- note tail call - else q[1] = new - end - return true - else q._go = true ; return false - end -end --- Queue a on queue q. --- --- If k is provided and the queue has previously drained, dequeue immediately --- as if k had passed to dequeue. This is useful when k will arrange for --- subsequent dequeues. -local function queue(q,a,k) - table.insert(q,a) - if k ~= nil and q._go then q._go = false; dequeue(q, k) end -end --- return a FIFO constructor -return function() - return { ['_go'] = true ; ['queue'] = queue ; ['dequeue'] = dequeue } -end diff --git a/host/pushinit.sh b/host/pushinit.sh index ffdf999..d62963a 100755 --- a/host/pushinit.sh +++ b/host/pushinit.sh @@ -3,9 +3,15 @@ set -e -u . ./host/pushcommon.sh +[ -d firm ] || { + echo "./firm should be a symbolic link to the nodemcu firmware" + exit 1 +} + +dopushcompile firm/lua_modules/fifo/fifo.lua +dopushcompile firm/lua_modules/fifo/fifosock.lua + dopushcompile util/diag.lua -dopushcompile fifo/fifo.lua -dopushcompile fifo/fifo-diag.lua dopushcompile tq/tq.lua dopushcompile tq/tq-diag.lua dopushcompile net/nwfnet.lua @@ -15,7 +21,6 @@ dopushcompile net/nwfnet-diag.lua #dopushtext net/conf/nwfnet.conf #dopushtext net/conf/nwfnet.cert #dopushtext net/conf/nwfnet.conf2 -dopushcompile net/fifosock.lua dopushcompile telnetd/telnetd.lua dopushcompile telnetd/telnetd-file.lua dopushcompile telnetd/telnetd-diag.lua diff --git a/net/fifosock.lua b/net/fifosock.lua deleted file mode 100644 index c7b6dd4..0000000 --- a/net/fifosock.lua +++ /dev/null @@ -1,118 +0,0 @@ --- Wrap a two-staged fifo around a socket's send, borrowing TerryE's --- scheme from NodeMCU's lua_examples/telnet/telnet.lua . --- --- Our fifos can take functions; these can be useful for either lazy --- generators or callbacks for parts of the stream having been sent. - -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 COALIMIT = 3 - -local concat = table.concat -local insert = table.insert -local gc = collectgarbage - -local fifo = OVL.fifo() - -return function(sock) - local fsmall, lsmall, fbig = {}, 0, fifo() - - local ssla, sslan = nil, 0 - local ssend = function(s,islast) - ns = nil - - -- Optimistically, try coalescing FIFO dequeues. But, don't try to - -- coalesce function outputs, since functions might be staging their - -- execution on the send event implied by being called. - - if type(s) == "function" then - if sslan ~= 0 then - sock:send(ssla) - ssla, sslan = nil, 0; gc() - return s, false -- stay as is and wait for :on("sent") - end - s, ns = s() - elseif type(s) == "string" and sslan < COALIMIT then - if sslan == 0 - then ssla, sslan = s, 1 - else ssla, sslan = ssla .. s, sslan + 1 - end - if islast then - -- this is shipping; if there's room, steal the small fifo, too - if sslan < COALIMIT then - sock:send(ssla .. concat(fsmall)) - fsmall, lsmall = {}, 0 - else - sock:send(ssla) - end - ssla, sslan = "", 0; gc() - return nil, false - else - return nil, true - end - end - - if s ~= nil then - if sslan == 0 then sock:send(s) else sock:send(ssla .. s) end - ssla, sslan = nil, 0; gc() - return ns or nil, false - elseif sslan ~= 0 then - assert (ns == nil) - sock:send(ssla) - ssla, sslan = nil, 0; gc() - return nil, false - else - assert (ns == nil) - return nil, true - end - end - - -- 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 - - -- Function? Go ahead and queue this thing in the right place. - if type(s) == "function" then promote(); fbig:queue(s, ssend); return; end - - s = tostring(s) - - -- 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, but cork sending in - -- case we're the head of line - local corked = false - while #s > BIGTHRESH + SPLITSLOP do - local pfx - pfx, s = s:sub(1,BIGTHRESH), s:sub(BIGTHRESH+1) - fbig:queue(pfx, function(t) corked = true; return t end) - end - - -- Big string? queue and maybe tx now - if #s > BIGTHRESH then fbig:queue(s, ssend) - -- small and empty line; start txing now. (maybe 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 - - -- if it happened that we corked the transmission above, uncork now - if corked then sendnext() end - end -end diff --git a/fifo/fifo-diag.lua b/old/fifo-diag.lua similarity index 100% rename from fifo/fifo-diag.lua rename to old/fifo-diag.lua diff --git a/test/fifotest.lua b/old/fifotest.lua similarity index 100% rename from test/fifotest.lua rename to old/fifotest.lua diff --git a/telnetd/telnetd-diag.lua b/telnetd/telnetd-diag.lua index 612171c..3d371d7 100644 --- a/telnetd/telnetd-diag.lua +++ b/telnetd/telnetd-diag.lua @@ -4,9 +4,12 @@ return { ["info"] = function(_,s) s(string.format("major=%d minor=%d dev=%d chip=%d flash=%d fs=%d fm=%d fs=%d",node.info())) end, ["heap"] = function(_,s) s(string.format("free=%d",node.heap())) end, ["fifo"] = function(_,s) if rtcfifo and rtcfifo.ready() ~= 0 then s(string.format("fifo=%d",rtcfifo.count())) else s("no rtcfifo") end end, - -- restart in one tick, so that network callbacks have a chance to fire + -- restart in some ticks, so that network callbacks have a chance to fire -- first, or else we might crash. Ick! - ["restart"] = function(_,s) tmr.create():alarm(1, tmr.ALARM_SINGLE, node.restart) end, + -- + -- Apparently we need "some" because the fifosock sometimes takes one to do its uncorking + -- and the network stack is its own monstrosity. Either way, probably fine. + ["restart"] = function(_,s) tmr.create():alarm(10, tmr.ALARM_SINGLE, node.restart) end, ["exec"] = function(l,s) local f, err = loadstring(l) if f diff --git a/telnetd/telnetd.lua b/telnetd/telnetd.lua index 9b0d4a6..148dcc7 100644 --- a/telnetd/telnetd.lua +++ b/telnetd/telnetd.lua @@ -26,12 +26,13 @@ function self.rx(tx,input,k) function(_) tx("?") k(true) end,tx) end function self.server(sock_) - local fsend = OVL.fifosock()(sock_) + local fsend = (require "fifosock").wrap(sock_) local function teardown(rawsock) rawsock:on("sent", nil) rawsock:on("receive", nil) rawsock:on("disconnection", nil) tryon("disconn",fsend) + fsend=nil end sock_:on("receive",function(s_,input) self.rx(fsend,input,function(c) if c then fsend("\n$ ") else s_:close() teardown(s_) end end) end) sock_:on("disconnection",function(s_, x) teardown(s_) end) diff --git a/test/fifosocktest.lua b/test/fifosocktest.lua deleted file mode 100644 index ecb1330..0000000 --- a/test/fifosocktest.lua +++ /dev/null @@ -1,110 +0,0 @@ -OVL={} -OVL.fifo = function() return dofile("./fifo/fifo.lua") end -package.loaded["fifosock"] = dofile("./net/fifosock.lua") - -verbose = 0 - -vprint = (verbose > 0) and print or function() end -outs = {} - -fakesock = { - cb = nil, - on = function(this, _, cb) vprint("CBSET") this.cb = cb end, - send = function(this, s) vprint("SEND", (verbose > 1) and s) table.insert(outs, s) end, -} -function sent() vprint("CB") fakesock.cb() end - -fsend = require "fifosock" (fakesock) -function nocoal() fsend(function() return nil end) end -function fcheck(x) - vprint ("CHECK", (verbose > 1) and x) - assert (#outs > 0) - assert (x == outs[1]) - table.remove(outs, 1) -end -function fsendc(x) fsend(x) fcheck(x) end -function fchecke() vprint("CHECKE") assert (#outs == 0) end - -fsendc("abracadabra none") -sent() ; fchecke() - -fsendc("abracadabra three") -fsend("short") -fsend("string") -fsend("build") -sent() ; fcheck("shortstringbuild") -sent() ; fchecke() - --- Hit default FSMALLLIM while building up -fsendc("abracadabra lots small") -for i = 1, 32 do fsend("a") end -nocoal() -for i = 1, 4 do fsend("a") end -sent() ; fcheck(string.rep("a", 32)) -sent() ; fcheck(string.rep("a", 4)) -sent() ; fchecke() - --- Hit string length while building up -fsendc("abracadabra overlong") -for i = 1, 10 do fsend(string.rep("a",32)) end -sent() ; fcheck(string.rep("a", 320)) -sent() ; fchecke() - --- Hit neither before sending a big string -fsendc("abracadabra mid long") -for i = 1, 6 do fsend(string.rep("a",32)) end -fsend(string.rep("b", 256)) -nocoal() -for i = 1, 6 do fsend(string.rep("c",32)) end -sent() ; fcheck(string.rep("a", 192) .. string.rep("b", 256)) -sent() ; fcheck(string.rep("c", 192)) -sent() ; fchecke() - --- send a huge string, verify that it coalesces -fsendc(string.rep("a",256) .. string.rep("b", 256) .. string.rep("c", 260)) -sent() ; fchecke() - --- send a huge string, verify that it coalesces save for the short bit at the end -fsend(string.rep("a",256) .. string.rep("b", 256) .. string.rep("c", 256) .. string.rep("d",256)) -fsend("e") -fcheck(string.rep("a",256) .. string.rep("b", 256) .. string.rep("c", 256)) -sent() ; fcheck(string.rep("d",256) .. "e") -sent() ; fchecke() - --- send enough that our 4x lookahead still leaves something in the queue -fsend(string.rep("a",512) .. string.rep("b", 512) .. string.rep("c", 512)) -fcheck(string.rep("a",512) .. string.rep("b", 512)) -sent() ; fcheck(string.rep("c",512)) -sent() ; fchecke() - --- test a lazy generator -local ix = 0 -local function gen() vprint("GEN", ix); ix = ix + 1; return ("a" .. ix), ix < 3 and gen end -fsend(gen) -fsend("b") -fcheck("a1") -sent() ; fcheck("a2") -sent() ; fcheck("a3") -sent() ; fcheck("b") -sent() ; fchecke() - --- test a completeion-like callback that does send text -local ix = 0 -local function gen() vprint("GEN"); ix = 1; return "efgh", nil end -fsend("abcd"); fsend(gen); fsend("ijkl") -assert (ix == 0) - fcheck("abcd"); assert (ix == 0) -sent() ; fcheck("efgh"); assert (ix == 1); ix = 0 -sent() ; fcheck("ijkl"); assert (ix == 0) -sent() ; fchecke() - --- and one that doesn't -local ix = 0 -local function gen() vprint("GEN"); ix = 1; return nil, nil end -fsend("abcd"); fsend(gen); fsend("ijkl") -assert (ix == 0) - fcheck("abcd"); assert (ix == 0) -sent() ; fcheck("ijkl"); assert (ix == 1); ix = 0 -sent() ; fchecke() ; assert (ix == 0) - -print("All tests OK") -- 2.50.1