Hello fellow Sqitchies,
I’ve been working on adding support for advisory locking to the engine, with implementations for MySQL and Postgres. See #589 for the details; I’d very much appreciate your thoughts here and/or review of the PR.
https://github.com/sqitchers/sqitch/pull/589
The way it works is by requiring engines to implement two methods (or else not to support locking):
* `try_lock`, which will try to create an exclusive lock and immediately return on success or failure
* `wait_lock`, which will try to create an exclusive lock and wait indefinitely to acquire it
Both methods should create exactly the same lock, statically defined by the engines, so that no other instance of Sqitch can be making changes to the database at the same time. The new `lock_destination` method is called at the start of both `deploy` and `revert`. It calls `try_lock`, and if it succeeds, returns, but if it doesn't, it emits a message about its inability to get the lock, then calls `wait_lock` to wait for it. The new `lock_timeout` attribute controls the wait timeout (60s by default), and `lock_destination` handles the timeout by raising an error, which will cause Sqitch to exit.
New tests in `t/engine.t` cover the behavior of `lock_destination`, while new testing and configuration tests engine-specific implementations in `t/lib/DBIEngineTest`.
I'd appreciate a close reading of this PR, as there are a few things we should consider. In particular:
* Do we really want this enabled by default? Or should we add configuration/options to turn it on? Or perhaps configuration/options to turn it off?
* Is using Sys::SigAction sufficient to handle the timeout, including on non-Unix hosts (Windows)? Or is it likely to run into issues/conflicts with the database? Might some database locking carry on even when the timeout kicks in? (I suspect it does, since I had to add code to repeatedly clear locks to the tests, though in practice it should not be an issue, since Sqitch will exit, not hang around holding onto locks unnecessarily. But MySQL in particular is weird).
Thoughts?
Thanks,
David