[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Running the GC to clear resource holding object on failure
- From: William Ahern <william@...>
- Date: Sat, 2 Aug 2014 19:59:15 -0700
On Sat, Aug 02, 2014 at 01:38:17PM +0200, Marc Balmer wrote:
<snip>
> The Lua script is called from C code using lua_pcall(). Now we notice a
> problem: What if the script contains an error and p:close() is never
> called? In this case the connection to the printer remains open until the
> GC kicks in, which can take long.
One option I sometimes use in my network servers is to run a thread on a
timer:
loop:wrap(function ()
while true do
cqueues.sleep(30)
collectgarbage()
end
end)
This is not a pretty solution. But it's simple and will work well in many
cases. But note that a single cycle is not always sufficient to destroy an
object.
A quicker hack would be to run the GC through two or three cycles if
lua_pcall returns error.
Another option is to run the critical code on a separate coroutine. Then
after you create the socket, register the coroutine along with the socket in
a weak table which is periodically scanned by another thread checking to see
if the status of the coroutine is "dead". If it's "dead", then it will close
the socket. That way you can limit the maximum amount of time (2 seconds, 10
seconds, whatever) that you can have a stale connection open. Either the GC
collects the socket, or your dead-socket-detector does.
Two of those options require a way to keep a separate coroutine running,
although not necessarily blocking execution of your process. You can still
do use this even if the primary event loop and application is in C. My
cqueues library exports an epoll/kqueue descriptor and a timeout value which
can be used to tell your C event loop when it should resume the Lua VM in
order to run the next event. Lots of my applications are mostly in C, with
Lua used to run ancillary scripts and other random network and timer related
tasks.
Of course there's the obvious solution, which is to use pcall inside your
Lua code, in a place that it knows to call :close on the socket if pcall
fails.