mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-29 15:49:13 +00:00
find cycle recovery strategy for a given cycle
This commit is contained in:
parent
fc826b0689
commit
bcffa4a836
3 changed files with 32 additions and 2 deletions
|
@ -378,6 +378,7 @@ where
|
|||
|
||||
Err(err) => {
|
||||
let err = runtime.report_unexpected_cycle(
|
||||
db.ops_database(),
|
||||
self.database_key_index,
|
||||
err,
|
||||
revision_now,
|
||||
|
|
|
@ -90,6 +90,7 @@ pub trait QueryFunction: Query {
|
|||
|
||||
/// Cycle recovery strategy: Is this query capable of recovering from
|
||||
/// a cycle that results from executing the function? If so, how?
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum CycleRecoveryStrategy {
|
||||
/// Cannot recover from cycles: panic.
|
||||
///
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::plumbing::CycleDetected;
|
||||
use crate::durability::Durability;
|
||||
use crate::plumbing::{CycleDetected, CycleRecoveryStrategy};
|
||||
use crate::revision::{AtomicRevision, Revision};
|
||||
use crate::{durability::Durability, Cancelled};
|
||||
use crate::Cancelled;
|
||||
use crate::{CycleError, Database, DatabaseKeyIndex, Event, EventKind};
|
||||
use log::debug;
|
||||
use parking_lot::lock_api::{RawRwLock, RawRwLockRecursive};
|
||||
|
@ -287,6 +288,7 @@ impl Runtime {
|
|||
/// Obviously, this should be user configurable at some point.
|
||||
pub(crate) fn report_unexpected_cycle(
|
||||
&self,
|
||||
db: &dyn Database,
|
||||
database_key_index: DatabaseKeyIndex,
|
||||
error: CycleDetected,
|
||||
changed_at: Revision,
|
||||
|
@ -297,6 +299,11 @@ impl Runtime {
|
|||
);
|
||||
|
||||
let cycle = self.find_cycle_participants(database_key_index, error);
|
||||
let crs = self.mutual_cycle_recovery_strategy(db, &cycle);
|
||||
debug!(
|
||||
"cycle recovery strategy {:?} for participants {:?}",
|
||||
crs, cycle
|
||||
);
|
||||
CycleError {
|
||||
cycle,
|
||||
changed_at,
|
||||
|
@ -304,6 +311,27 @@ impl Runtime {
|
|||
}
|
||||
}
|
||||
|
||||
fn mutual_cycle_recovery_strategy(
|
||||
&self,
|
||||
db: &dyn Database,
|
||||
cycle: &[DatabaseKeyIndex],
|
||||
) -> CycleRecoveryStrategy {
|
||||
let crs = db.cycle_recovery_strategy(cycle[0]);
|
||||
if let Some(key) = cycle[1..]
|
||||
.iter()
|
||||
.copied()
|
||||
.find(|&key| db.cycle_recovery_strategy(key) != crs)
|
||||
{
|
||||
debug!("mutual_cycle_recovery_strategy: cycle had multiple strategies ({:?} for {:?} vs {:?} for {:?})",
|
||||
crs, cycle[0],
|
||||
db.cycle_recovery_strategy(key), key
|
||||
);
|
||||
CycleRecoveryStrategy::Panic
|
||||
} else {
|
||||
crs
|
||||
}
|
||||
}
|
||||
|
||||
fn find_cycle_participants(
|
||||
&self,
|
||||
database_key_index: DatabaseKeyIndex,
|
||||
|
|
Loading…
Reference in a new issue