Harden durable replay and lock recovery
This commit is contained in:
parent
20ea9557fd
commit
182b4d58c7
1 changed files with 156 additions and 22 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use sqlx::{PgPool, Postgres, Transaction};
|
||||
|
||||
use crate::error::DurableError;
|
||||
|
|
@ -33,6 +34,29 @@ pub async fn set_lock_timeout(tx: &mut PgTx<'_>) -> Result<(), DurableError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Advisory lock class reserved for mutation ledger identity locks.
|
||||
/// Feature packages must not use this class.
|
||||
pub const ADVISORY_CLASS_MUTATION: i32 = 1;
|
||||
|
||||
/// Advisory lock class for application and feature-package locks.
|
||||
/// Prefer this (or higher package-owned classes) over the mutation class.
|
||||
pub const ADVISORY_CLASS_APP: i32 = 2;
|
||||
|
||||
/// Mixes the class into a 64-bit key to separate lock domains without reducing
|
||||
/// the PostgreSQL `bigint` identity space.
|
||||
#[must_use]
|
||||
pub fn advisory_key(class: i32, key: i32) -> i64 {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"remora.advisory.v1");
|
||||
hasher.update(class.to_be_bytes());
|
||||
hasher.update(key.to_be_bytes());
|
||||
let digest = hasher.finalize();
|
||||
i64::from_be_bytes([
|
||||
digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7],
|
||||
])
|
||||
}
|
||||
|
||||
/// Transaction-scoped advisory lock on a domain-separated 64-bit key.
|
||||
pub async fn advisory_xact_lock(tx: &mut PgTx<'_>, key: i64) -> Result<(), DurableError> {
|
||||
sqlx::query("SELECT pg_advisory_xact_lock($1)")
|
||||
.bind(key)
|
||||
|
|
|
|||
Loading…
Reference in a new issue