Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: convenient wrapper for Postgres advisory locks #1641

Merged
merged 1 commit into from
Mar 25, 2022

Conversation

abonander
Copy link
Collaborator

@abonander abonander commented Jan 19, 2022

While working on a Launchbadge project, I realized I needed a way to provide mutual exclusion synchronized with the database so that multiple instances of a server application don't try to perform the same side-effecting operation, but the locking scheme I wanted didn't fit neatly onto standard row- or table-level locking.

I excitedly remembered that Postgres has advisory locks with application-defined semantics, but quickly realized they were somewhat unwieldy to use for our purposes.

There's transaction-scoped advisory locks, which would work well except that because I was doing side-effecting operations, I wanted the updates I was making to the database to be published immediately, and it seemed unreasonable to check out two connections from the pool, with one purely existing to hold a transaction for automatically managed advisory locks.

There's also session-scoped advisory locks, which are held until manually released or until the connection is closed. This was better, but because I'm using PgPool I wanted to make sure the lock is released when the connection is returned to the pool. However, some ding-dong (i.e. me) decided that .after_release() didn't need to support async functionality, because... I don't remember why.

So I ended up writing a wrapper that spawns a task on drop to execute pg_advisory_unlock() on the connection before letting it return to the pool, so I could get the project working, but I immediately felt like this should be something that lives in SQLx, and could be more convenient to use and optimally implemented that way.

Thus began a two-and-a-half hour nerd snipe that culminated in this.

TODO:

  • integration tests
  • more docs (not sure what I meant here)

@abonander abonander force-pushed the ab/pg-advisory-lock branch from 3f4e859 to e72714f Compare January 20, 2022 02:30
@abonander abonander force-pushed the ab/pg-advisory-lock branch from e72714f to f21abec Compare March 24, 2022 20:56
@abonander abonander marked this pull request as ready for review March 24, 2022 20:58
@abonander abonander force-pushed the ab/pg-advisory-lock branch 2 times, most recently from cb78292 to 9b9b5ff Compare March 24, 2022 21:24
@abonander abonander force-pushed the ab/pg-advisory-lock branch from 9b9b5ff to d80a300 Compare March 24, 2022 21:33
@abonander abonander merged commit e1817f0 into master Mar 25, 2022
@abonander abonander deleted the ab/pg-advisory-lock branch March 25, 2022 00:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant