This is an experimental program that wraps an executable program inside of an exclusive lock provided by PostgreSQL's pg_try_advisory_lock.
pg_try_advisory_lock is a sibling of pg_advisory_lock, which is a locking
function with two signatures. One accepts a 64-bit integer, and the other accepts 2 32-bit integers. The main difference between pg_advisory_lock and pg_try_advisory_lock is that pg_try_advisory_lock does not wait until a lock
becomes available. Instead, pg_try_advisory_lock returns immediately with a t if it successfully acquired the lock, and f if it was unable to acquire it.
One last behavior that is important to note: if the connection to PostgreSQL is
severed, any lock acquired via pg_try_advisory_lock is automatically released.
The heimdall program has four required arguments:
- A database URL (
postgres://postgres@localhost/postgres?sslmode=disable) - A lock namespace
- A lock name
- A command to wrap
An example wrapping the ls command looks like:
$ heimdall \
--database "postgres://postgres@localhost/postgres?sslmode=disable" \
--namespace joker \
--name test \
lsA quick way to test an exclusive lock is to use sleep as the command.Executing heimdall once with sleep 10 and then immediately with another
command in another shell should prevent the second command from executing.
Induce a deep sleep:
$ heimdall \
--database "postgres://postgres@localhost/postgres?sslmode=disable" \
--namespace joker \
--name test \
sleep 10Try to get the date:
$ heimdall \
--database "postgres://postgres@localhost/postgres?sslmode=disable" \
--namespace joker \
--name test \
dateThe local tests use testcontainers-go to automatically spin up a PostgreSQL container during test execution. Simply run:
$ make testDocker must be running on your system for the tests to execute successfully.
I was made aware of pg_try_advisory_lock through @ryandotsmith's work in lock-smith.