use std::time::Duration;
use serde::{Deserialize, Serialize};
pub use linkrs_core::types::space::IsolationLevel as SpaceIsolationLevel;
pub use linkrs_core::types::DurabilityLevel;
pub use linkrs_core::types::TransactionIsolationLevel as IsolationLevel;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum ConcurrencyMode {
#[default]
Optimistic,
SingleWriter,
}
#[derive(Debug, Clone, Copy)]
pub struct RetryConfig {
pub max_retries: u32,
pub initial_delay: Duration,
pub backoff_multiplier: f64,
pub max_delay: Duration,
}
impl Default for RetryConfig {
fn default() -> Self {
Self {
max_retries: 3,
initial_delay: Duration::from_millis(100),
backoff_multiplier: 2.0,
max_delay: Duration::from_secs(10),
}
}
}
impl RetryConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_max_retries(mut self, max_retries: u32) -> Self {
self.max_retries = max_retries;
self
}
pub fn with_initial_delay(mut self, delay: Duration) -> Self {
self.initial_delay = delay;
self
}
pub fn with_backoff_multiplier(mut self, multiplier: f64) -> Self {
self.backoff_multiplier = multiplier;
self
}
pub fn with_max_delay(mut self, delay: Duration) -> Self {
self.max_delay = delay;
self
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct TransactionOptions {
pub timeout: Option<Duration>,
pub read_only: bool,
pub long_read: bool,
pub durability: DurabilityLevel,
pub isolation_level: IsolationLevel,
pub query_timeout: Option<Duration>,
pub statement_timeout: Option<Duration>,
pub idle_timeout: Option<Duration>,
}
impl TransactionOptions {
pub fn new() -> Self {
Self::default()
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn read_only(mut self) -> Self {
self.read_only = true;
self
}
pub fn long_read(mut self) -> Self {
self.long_read = true;
self
}
pub fn with_durability(mut self, durability: DurabilityLevel) -> Self {
self.durability = durability;
self
}
pub fn with_isolation_level(mut self, level: IsolationLevel) -> Self {
self.isolation_level = level;
self
}
pub fn with_query_timeout(mut self, timeout: Duration) -> Self {
self.query_timeout = Some(timeout);
self
}
pub fn with_statement_timeout(mut self, timeout: Duration) -> Self {
self.statement_timeout = Some(timeout);
self
}
pub fn with_idle_timeout(mut self, timeout: Duration) -> Self {
self.idle_timeout = Some(timeout);
self
}
}
#[derive(Debug, Clone)]
pub struct TransactionConfig {
pub timeout: Duration,
pub durability: DurabilityLevel,
pub isolation_level: IsolationLevel,
pub query_timeout: Option<Duration>,
pub statement_timeout: Option<Duration>,
pub idle_timeout: Option<Duration>,
pub auto_commit: bool,
pub max_mutation_count: u64,
pub max_undo_bytes: u64,
pub budget_warning_threshold: f64,
pub concurrency_mode: ConcurrencyMode,
pub serializable_full_scan_threshold: Option<usize>,
}
impl Default for TransactionConfig {
fn default() -> Self {
Self {
timeout: Duration::from_secs(30),
durability: DurabilityLevel::default(),
isolation_level: IsolationLevel::default(),
query_timeout: None,
statement_timeout: None,
idle_timeout: None,
auto_commit: false,
max_mutation_count: 100_000,
max_undo_bytes: 128 * 1024 * 1024,
budget_warning_threshold: 0.8,
concurrency_mode: ConcurrencyMode::Optimistic,
serializable_full_scan_threshold: Some(10_000),
}
}
}
impl TransactionConfig {
pub fn new() -> Self {
Self::default()
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn with_durability(mut self, durability: DurabilityLevel) -> Self {
self.durability = durability;
self
}
pub fn with_isolation_level(mut self, level: IsolationLevel) -> Self {
self.isolation_level = level;
self
}
pub fn with_query_timeout(mut self, timeout: Option<Duration>) -> Self {
self.query_timeout = timeout;
self
}
pub fn with_statement_timeout(mut self, timeout: Option<Duration>) -> Self {
self.statement_timeout = timeout;
self
}
pub fn with_idle_timeout(mut self, timeout: Option<Duration>) -> Self {
self.idle_timeout = timeout;
self
}
pub fn with_auto_commit(mut self, auto_commit: bool) -> Self {
self.auto_commit = auto_commit;
self
}
pub fn with_max_mutation_count(mut self, max: u64) -> Self {
self.max_mutation_count = max;
self
}
pub fn with_max_undo_bytes(mut self, max: u64) -> Self {
self.max_undo_bytes = max;
self
}
pub fn with_budget_warning_threshold(mut self, threshold: f64) -> Self {
self.budget_warning_threshold = threshold.clamp(0.0, 1.0);
self
}
pub fn with_concurrency_mode(mut self, mode: ConcurrencyMode) -> Self {
self.concurrency_mode = mode;
self
}
pub fn with_serializable_full_scan_threshold(mut self, threshold: Option<usize>) -> Self {
self.serializable_full_scan_threshold = threshold;
self
}
}
#[derive(Debug, Clone)]
pub struct TransactionManagerConfig {
pub default_timeout: Duration,
pub max_concurrent_transactions: usize,
pub auto_cleanup: bool,
pub commit_retry_attempts: u32,
pub abort_retry_attempts: u32,
pub txn_config: TransactionConfig,
pub in_memory: bool,
pub group_commit_enabled: bool,
pub group_commit_timeout: Duration,
pub auto_checkpoint_after_commit: bool,
pub auto_checkpoint_commit_threshold: u64,
pub default_lease_ttl: Duration,
pub long_read_max_live_leases: usize,
pub long_read_max_pin_secs: u64,
}
impl Default for TransactionManagerConfig {
fn default() -> Self {
Self {
default_timeout: Duration::from_secs(30),
max_concurrent_transactions: 1000,
auto_cleanup: true,
commit_retry_attempts: 3,
abort_retry_attempts: 3,
txn_config: TransactionConfig::default(),
in_memory: false,
group_commit_enabled: true,
group_commit_timeout: Duration::from_secs(30),
auto_checkpoint_after_commit: true,
auto_checkpoint_commit_threshold: 1,
default_lease_ttl: Duration::from_secs(300),
long_read_max_live_leases: 64,
long_read_max_pin_secs: 300,
}
}
}
impl TransactionManagerConfig {
pub fn with_in_memory(mut self, in_memory: bool) -> Self {
self.in_memory = in_memory;
self
}
pub fn with_group_commit(mut self, enabled: bool) -> Self {
self.group_commit_enabled = enabled;
self
}
pub fn with_group_commit_timeout(mut self, timeout: Duration) -> Self {
self.group_commit_timeout = timeout;
self
}
pub fn with_auto_checkpoint_after_commit(mut self, enabled: bool) -> Self {
self.auto_checkpoint_after_commit = enabled;
self
}
pub fn with_auto_checkpoint_commit_threshold(mut self, threshold: u64) -> Self {
self.auto_checkpoint_commit_threshold = threshold;
self
}
pub fn is_in_memory(&self) -> bool {
self.in_memory
}
}