fix(waku_archive): only allow a single instance to execute migrations (#2736)

This commit is contained in:
richΛrd 2024-05-31 12:08:16 -04:00 committed by GitHub
parent 8b42f199ba
commit 88b8e1867a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 0 deletions

View File

@ -72,6 +72,16 @@ proc migrate*(
# Load migration scripts
let scripts = pg_migration_manager.getMigrationScripts(currentVersion, targetVersion)
# Lock the db
(await driver.acquireDatabaseLock()).isOkOr:
error "failed to acquire lock", error = error
return err("failed to lock the db")
defer:
(await driver.releaseDatabaseLock()).isOkOr:
error "failed to release lock", error = error
return err("failed to unlock the db.")
# Run the migration scripts
for script in scripts:
for statement in script.breakIntoStatements():

View File

@ -853,6 +853,42 @@ proc sleep*(
return ok()
proc acquireDatabaseLock*(
s: PostgresDriver, lockId: int = 841886
): Future[ArchiveDriverResult[void]] {.async.} =
## Acquire an advisory lock (useful to avoid more than one application running migrations at the same time)
let locked = (
await s.getStr(
fmt"""
SELECT pg_try_advisory_lock({lockId})
"""
)
).valueOr:
return err("error acquiring a lock: " & error)
if locked == "f":
return err("another waku instance is currently executing a migration")
return ok()
proc releaseDatabaseLock*(
s: PostgresDriver, lockId: int = 841886
): Future[ArchiveDriverResult[void]] {.async.} =
## Acquire an advisory lock (useful to avoid more than one application running migrations at the same time)
let unlocked = (
await s.getStr(
fmt"""
SELECT pg_advisory_unlock({lockId})
"""
)
).valueOr:
return err("error releasing a lock: " & error)
if unlocked == "f":
return err("could not release advisory lock")
return ok()
proc performWriteQuery*(
s: PostgresDriver, query: string
): Future[ArchiveDriverResult[void]] {.async.} =