On a nodemcu, I'm using a closure to send a file over a socket, like this:
function sendfile(sock, name)
local fd = file.open(name, "r")
function sendchunk()
local data = fd:read()
if data then
sock:send(data)
else
fd:close()
sock:close()
end
end
sock:on("sent", sendchunk)
sendchunk()
end
After transferring a few files, the interpreter panics due to "not enough memory". I can imagine this may be due to closure still hanging around. It would be difficult for the garbage collector to determine that sendchunk() will not be called again once the file and socket are closed.
Unfortunately my googling has not revealed a method to end the closure and free the memory it is using.
Am I using a wrong method to do this? Should I perhaps use an anonymous function or something?
It was already mentioned here that
:on()
invocation saves reference to callback closure inside Lua registry.I guess this closure will be cleared from Lua registry inside
__gc
metamethod ofsock
object,but
sock
object will not be collected if the closure referencessock
object.To solve this problem you should avoid hard-coding a reference to
sock
upvalue in the body ofsendchunk()
function.For example, exploit the fact that the first argument passed to callback function is always the socket object.