66 lines
2.0 KiB
Rust
66 lines
2.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use uuid::Uuid;
|
|
|
|
use crate::cache::AppCache;
|
|
use crate::cache::redis::AppRedis;
|
|
use crate::config::AppConfig;
|
|
use crate::error::AppError;
|
|
use crate::etcd::EtcdRegistry;
|
|
use crate::models::db::AppDatabase;
|
|
use crate::queue::NatsQueue;
|
|
use crate::service::im::events::ImEventBus;
|
|
use crate::storage::s3::AppS3Storage;
|
|
|
|
/// Shared infrastructure context for all domain services.
|
|
///
|
|
/// Each sub-service (Auth, User, Workspace, Repo) holds an `Arc<ServiceContext>`
|
|
/// so they share the same database, cache, and other infrastructure without
|
|
/// duplicating ownership.
|
|
#[derive(Clone)]
|
|
pub struct ServiceContext {
|
|
pub version: String,
|
|
pub db: AppDatabase,
|
|
pub redis: AppRedis,
|
|
pub cache: Arc<AppCache>,
|
|
pub config: AppConfig,
|
|
pub storage: AppS3Storage,
|
|
/// etcd-based service registry for discovering git and mail RPC services.
|
|
pub registry: Arc<EtcdRegistry>,
|
|
/// NATS JetStream queue for real-time event broadcasting.
|
|
pub nats: Arc<NatsQueue>,
|
|
pub im_events: Arc<ImEventBus>,
|
|
}
|
|
|
|
impl ServiceContext {
|
|
/// Run a block of work inside a database transaction.
|
|
///
|
|
/// - Begins a transaction on the writer pool
|
|
/// - Sets `app.current_user_id` for RLS / audit triggers
|
|
/// - Commits on success, rolls back on error
|
|
pub async fn run_in_transaction<F, Fut, T>(&self, user_uid: Uuid, f: F) -> Result<T, AppError>
|
|
where
|
|
F: FnOnce(&mut sqlx::Transaction<'_, sqlx::Postgres>) -> Fut,
|
|
Fut: std::future::Future<Output = Result<T, AppError>>,
|
|
{
|
|
let mut txn = self
|
|
.db
|
|
.writer()
|
|
.begin()
|
|
.await
|
|
.map_err(|_| AppError::TxnError)?;
|
|
|
|
sqlx::query("SET LOCAL app.current_user_id = $1")
|
|
.bind(user_uid)
|
|
.execute(&mut *txn)
|
|
.await
|
|
.map_err(AppError::Database)?;
|
|
|
|
let result = f(&mut txn).await?;
|
|
|
|
txn.commit().await.map_err(|_| AppError::TxnError)?;
|
|
|
|
Ok(result)
|
|
}
|
|
}
|