Add PostgreSQL DurableStore substrate for WP-03
Introduce remora-durable with pool/migrations, a RemoraApiMutation-shaped ledger, claim-fenced outbox projection, CAS helpers, and keyset cursors, plus a kind Job acceptance suite against the hermetic fixture.
This commit is contained in:
parent
af8bb1a03a
commit
957d170150
1 changed files with 3203 additions and 18 deletions
42
crates/remora-durable/src/tx.rs
Normal file
42
crates/remora-durable/src/tx.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
use sqlx::{PgPool, Postgres, Transaction};
|
||||
|
||||
use crate::error::DurableError;
|
||||
|
||||
pub type PgTx<'a> = Transaction<'a, Postgres>;
|
||||
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
||||
|
||||
pub async fn with_transaction<T, F>(pool: &PgPool, work: F) -> Result<T, DurableError>
|
||||
where
|
||||
F: for<'c> FnOnce(&'c mut PgTx<'_>) -> BoxFuture<'c, Result<T, DurableError>>,
|
||||
{
|
||||
let mut tx = pool.begin().await?;
|
||||
match work(&mut tx).await {
|
||||
Ok(value) => {
|
||||
tx.commit().await?;
|
||||
Ok(value)
|
||||
}
|
||||
Err(error) => {
|
||||
let _ = tx.rollback().await;
|
||||
Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Bound how long this transaction waits for row or advisory locks.
|
||||
pub async fn set_lock_timeout(tx: &mut PgTx<'_>) -> Result<(), DurableError> {
|
||||
sqlx::query("SET LOCAL lock_timeout = '5s'")
|
||||
.execute(tx.as_mut())
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn advisory_xact_lock(tx: &mut PgTx<'_>, key: i64) -> Result<(), DurableError> {
|
||||
sqlx::query("SELECT pg_advisory_xact_lock($1)")
|
||||
.bind(key)
|
||||
.execute(tx.as_mut())
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Reference in a new issue