Revise fifo{,sock} (#2671)

Fixes to #2650:

- Convert fifosock to returning tables containing ctors
- Improve docs
- Add a missed :on("sent", nil) in the http server
This commit is contained in:
Nathaniel Wesley Filardo 2019-02-17 18:32:16 +00:00 committed by Terry Ellison
parent d77666c0e8
commit 1070466feb
5 changed files with 28 additions and 15 deletions

View File

@ -3,23 +3,35 @@
| :----- | :-------------------- | :---------- | :------ |
| 2019-02-10 | [TerryE](https://github.com/TerryE) | [nwf](https://github.com/nwf) | [fifosock.lua](../../lua_modules/fifo/fifosock.lua) |
This module provides a convenient, efficient wrapper around the `net.socket`
`send` method. It ensures in-order transmission while striving to minimize
memory footprint and packet count by coalescing queued strings. It also serves
as a detailed, worked example of the `fifo` module.
This module provides a moderately convenient, efficient wrapper around the
`net.socket` `send` method. It ensures in-order transmission while striving to
minimize memory footprint and packet count by coalescing queued strings. It
also serves as a detailed, worked example of the `fifo` module.
## Use
```lua
ssend = (require "fifosock")(sock)
ssend = (require "fifosock").wrap(sock)
ssend("hello, ") ssend("world\n")
-- when finished
ssend = nil
sock:on("sent", nil)
```
Once the `sock`et has been wrapped, one should use only the resulting `ssend`
function in lieu of `sock:send`, and one should not change the
`sock:on("sent")` callback.
`sock:on("sent")` callback for the duration of the connection.
### Advanced Use
Use of this module creates a circular reference through the Lua registry: the
socket points at the fifosock wrapper, which points back at the socket. As
such, it is vitally important to break this cycle when the socket has outlived
its use. **The usual garbage collection will not be able to reclaim abandoned
wrapped sockets**. The user of `fifosock` must, when disposing of the socket,
unwire the wrapper, by calling `sock:on("sent", nil)` and should drop all
references to `ssend`; a convenient place to do this is in the
`sock:on("disconnect")` callback.
## Advanced Use
In addition to passing strings representing part of the stream to be sent, it
is possible to pass the resulting `ssend` function *functions*. These

View File

@ -31,7 +31,7 @@ local node, table, tmr, wifi, uwrite, tostring =
node, table, tmr, wifi, uart.write, tostring
local function telnet_listener(socket)
local queueLine = (require "fifosock")(socket)
local queueLine = (require "fifosock").wrap(socket)
local function receiveLine(s, line)
node.input(line)

View File

@ -15,11 +15,9 @@ local concat = table.concat
local insert = table.insert
local gc = collectgarbage
local fifo = require "fifo"
return function(sock)
local function wrap(sock)
-- the two fifos
local fsmall, lsmall, fbig = {}, 0, fifo.new()
local fsmall, lsmall, fbig = {}, 0, (require "fifo").new()
-- ssend last aggregation string and aggregate count
local ssla, sslan = nil, 0
@ -132,3 +130,5 @@ return function(sock)
end
end
end
return { wrap = wrap }

View File

@ -33,7 +33,7 @@ local fakesock = {
local function sent() vprint("SENT") fakesock.cb() end
-- And wrap a fifosock around this fake socket
local fsend = require "fifosock" (fakesock)
local fsend = (require "fifosock").wrap(fakesock)
-- Verify that the next unconsumed output is as indicated
local function fcheck(x)

View File

@ -79,7 +79,7 @@ do
------------------------------------------------------------------------------
local http_handler = function(handler)
return function(conn)
local csend = (require "fifosock")(conn)
local csend = (require "fifosock").wrap(conn)
local cfini = function()
conn:on("receive", nil)
conn:on("disconnection", nil)
@ -89,6 +89,7 @@ do
local buf = ""
local method, url
local ondisconnect = function(conn)
conn.on("sent", nil)
collectgarbage("collect")
end
-- header parser