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) | | 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` This module provides a moderately convenient, efficient wrapper around the
`send` method. It ensures in-order transmission while striving to minimize `net.socket` `send` method. It ensures in-order transmission while striving to
memory footprint and packet count by coalescing queued strings. It also serves minimize memory footprint and packet count by coalescing queued strings. It
as a detailed, worked example of the `fifo` module. also serves as a detailed, worked example of the `fifo` module.
## Use ## Use
```lua ```lua
ssend = (require "fifosock")(sock) ssend = (require "fifosock").wrap(sock)
ssend("hello, ") ssend("world\n") 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` 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 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 In addition to passing strings representing part of the stream to be sent, it
is possible to pass the resulting `ssend` function *functions*. These 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 node, table, tmr, wifi, uart.write, tostring
local function telnet_listener(socket) local function telnet_listener(socket)
local queueLine = (require "fifosock")(socket) local queueLine = (require "fifosock").wrap(socket)
local function receiveLine(s, line) local function receiveLine(s, line)
node.input(line) node.input(line)

View File

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

View File

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

View File

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