[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Error handling (was Re: [ANN] Lua 5.3.0 (final) now available)
- From: William Ahern <william@...>
- Date: Tue, 20 Jan 2015 13:21:28 -0800
On Mon, Jan 19, 2015 at 11:34:50PM -0600, Andrew Starks wrote:
> On Monday, January 19, 2015, William Ahern <email@example.com>
> > Maybe you already do this, but in Lua 5.2 and 5.3 you can catch the leak by
> > using the object to index a weak table, where you store a table with a __gc
> > metamethod hook to trigger your cleanup logic. (In Lua 5.1 you can use the
> > undocumented newproxy in lieu of table __gc metamethods.)
> Wow. This is a great idea, if I'm following it.
> Do I have this correct: when you are doing something that may need to be
> rolled back, you attach the roll back to a table with weak keys. If failure
> happens, the key is collected because the other references die with the
> failure. This releases the value associated with the key, which is a table
> that has a __gc method; the cleanup function.
> You could wrap pcall to take the clean up function as an argument and it
> would create the fail safe and also dissarm it, should the call succeed.
Sure, although I'm not sure of the utility in that case because at the pcall
point you already know if something succeeded or failed, have access to the
relevant state, and know how to clean up. If you can add the logic there you
probably don't need the above trick.
I tend to use it more for, e.g., object factories that instantiate and cache
a limited number of resources. Using the above method I handle the case of
buggy code not returning an object back into the cache.
A more low-level example:
local lck = assert(mutex:lock())
I use the weak table trick to detect if the object lck is leaked while in a
locked state. If so, then I wakeup any threads waiting in mutex:lock and
return an error. Note that in this case any pcall further up the stack
wouldn't know anything about mutex, lck, or how to signal other threads that
the transaction that the mutex is guarding is fubar'd. The closest pcall
might be resuming a coroutine, and not know anything about the business
logic. Instead, mutex:lock arms, and lck:unlock disarms the failsafe.