atagen

macltok

public
Star0
Watch0
c9f0fd0ee1cccdd0048f121ba1c8ab1f12482f5d
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git

Blame: src/repair_model.rs

c9f0fd0ee1ccatagen2026-10-25 06:16 UTC1
use ruma::{OwnedEventId, OwnedRoomId, OwnedTransactionId};
80381e06a573atagen2026-10-25 03:02 UTC2
80381e06a573atagen2026-10-25 03:02 UTC3
#[cfg(feature = "serde")]
80381e06a573atagen2026-10-25 03:02 UTC4
use serde::{Deserialize, Serialize};
80381e06a573atagen2026-10-25 03:02 UTC5
80381e06a573atagen2026-10-25 03:02 UTC6
use crate::Error;
80381e06a573atagen2026-10-25 03:02 UTC7
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC8
#[derive(Clone, Debug, PartialEq, Eq)]
80381e06a573atagen2026-10-25 03:02 UTC9
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC10
pub enum HistoryRepairPolicy {
80381e06a573atagen2026-10-25 03:02 UTC11
    StartRecent,
80381e06a573atagen2026-10-25 03:02 UTC12
    Bridge,
80381e06a573atagen2026-10-25 03:02 UTC13
    BridgeShortGaps { threshold_ms: u64 },
80381e06a573atagen2026-10-25 03:02 UTC14
}
80381e06a573atagen2026-10-25 03:02 UTC15
80381e06a573atagen2026-10-25 03:02 UTC16
impl Default for HistoryRepairPolicy {
80381e06a573atagen2026-10-25 03:02 UTC17
    fn default() -> Self {
80381e06a573atagen2026-10-25 03:02 UTC18
        Self::StartRecent
80381e06a573atagen2026-10-25 03:02 UTC19
    }
80381e06a573atagen2026-10-25 03:02 UTC20
}
80381e06a573atagen2026-10-25 03:02 UTC21
80381e06a573atagen2026-10-25 03:02 UTC22
#[derive(Clone, Debug, PartialEq)]
80381e06a573atagen2026-10-25 03:02 UTC23
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC24
pub struct HistoryRepairBudget {
80381e06a573atagen2026-10-25 03:02 UTC25
    pub max_pages: u16,
80381e06a573atagen2026-10-25 03:02 UTC26
    pub max_events: u32,
80381e06a573atagen2026-10-25 03:02 UTC27
    pub max_duration_ms: u64,
80381e06a573atagen2026-10-25 03:02 UTC28
}
80381e06a573atagen2026-10-25 03:02 UTC29
80381e06a573atagen2026-10-25 03:02 UTC30
impl Default for HistoryRepairBudget {
80381e06a573atagen2026-10-25 03:02 UTC31
    fn default() -> Self {
80381e06a573atagen2026-10-25 03:02 UTC32
        Self {
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC33
            max_pages: 4,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC34
            max_events: 200,
80381e06a573atagen2026-10-25 03:02 UTC35
            max_duration_ms: 15_000,
80381e06a573atagen2026-10-25 03:02 UTC36
        }
80381e06a573atagen2026-10-25 03:02 UTC37
    }
80381e06a573atagen2026-10-25 03:02 UTC38
}
80381e06a573atagen2026-10-25 03:02 UTC39
80381e06a573atagen2026-10-25 03:02 UTC40
#[derive(Clone, Debug, PartialEq)]
80381e06a573atagen2026-10-25 03:02 UTC41
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC42
pub enum HistoryRepairCommand {
80381e06a573atagen2026-10-25 03:02 UTC43
    Start {
80381e06a573atagen2026-10-25 03:02 UTC44
        room_id: OwnedRoomId,
80381e06a573atagen2026-10-25 03:02 UTC45
        policy: Option<HistoryRepairPolicy>,
80381e06a573atagen2026-10-25 03:02 UTC46
        budget: HistoryRepairBudget,
80381e06a573atagen2026-10-25 03:02 UTC47
    },
80381e06a573atagen2026-10-25 03:02 UTC48
    Continue {
80381e06a573atagen2026-10-25 03:02 UTC49
        room_id: OwnedRoomId,
80381e06a573atagen2026-10-25 03:02 UTC50
        budget: HistoryRepairBudget,
80381e06a573atagen2026-10-25 03:02 UTC51
    },
80381e06a573atagen2026-10-25 03:02 UTC52
    Cancel {
80381e06a573atagen2026-10-25 03:02 UTC53
        room_id: OwnedRoomId,
80381e06a573atagen2026-10-25 03:02 UTC54
    },
80381e06a573atagen2026-10-25 03:02 UTC55
    StartRecent {
80381e06a573atagen2026-10-25 03:02 UTC56
        room_id: OwnedRoomId,
80381e06a573atagen2026-10-25 03:02 UTC57
    },
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC58
    FillGap {
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC59
        room_id: OwnedRoomId,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC60
        gap_id: OwnedTransactionId,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC61
    },
80381e06a573atagen2026-10-25 03:02 UTC62
    GetPolicy,
80381e06a573atagen2026-10-25 03:02 UTC63
    SetPolicy(HistoryRepairPolicy),
80381e06a573atagen2026-10-25 03:02 UTC64
}
80381e06a573atagen2026-10-25 03:02 UTC65
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC66
#[derive(Clone, Debug, PartialEq, Eq)]
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC67
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC68
pub struct HistoryGap {
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC69
    pub id: OwnedTransactionId,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC70
    pub older_boundary: Option<OwnedEventId>,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC71
    pub newer_boundary: Option<OwnedEventId>,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC72
    pub lifecycle: HistoryGapLifecycle,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC73
    pub continuity: HistoryContinuity,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC74
    pub failure: Option<String>,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC75
}
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC76
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC77
#[derive(Clone, Debug, PartialEq, Eq)]
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC78
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC79
pub enum HistoryGapLifecycle {
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC80
    Idle,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC81
    Fetching,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC82
    Paused,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC83
    Failed,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC84
    Unavailable,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC85
}
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC86
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC87
#[derive(Clone, Debug, PartialEq, Eq)]
80381e06a573atagen2026-10-25 03:02 UTC88
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC89
pub enum HistoryRepairStrategy {
80381e06a573atagen2026-10-25 03:02 UTC90
    Recent,
80381e06a573atagen2026-10-25 03:02 UTC91
    Overlap,
80381e06a573atagen2026-10-25 03:02 UTC92
    Bridge,
80381e06a573atagen2026-10-25 03:02 UTC93
}
80381e06a573atagen2026-10-25 03:02 UTC94
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC95
#[derive(Clone, Debug, PartialEq, Eq)]
80381e06a573atagen2026-10-25 03:02 UTC96
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC97
pub enum HistoryContinuity {
80381e06a573atagen2026-10-25 03:02 UTC98
    Unresolved,
80381e06a573atagen2026-10-25 03:02 UTC99
    Verified,
80381e06a573atagen2026-10-25 03:02 UTC100
    AccessibleStart,
80381e06a573atagen2026-10-25 03:02 UTC101
}
80381e06a573atagen2026-10-25 03:02 UTC102
80381e06a573atagen2026-10-25 03:02 UTC103
#[derive(Clone, Debug, PartialEq)]
80381e06a573atagen2026-10-25 03:02 UTC104
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC105
pub enum HistoryRepairPhase {
80381e06a573atagen2026-10-25 03:02 UTC106
    FetchingRecent,
80381e06a573atagen2026-10-25 03:02 UTC107
    Bridging,
80381e06a573atagen2026-10-25 03:02 UTC108
    Ready,
80381e06a573atagen2026-10-25 03:02 UTC109
    Paused,
80381e06a573atagen2026-10-25 03:02 UTC110
}
80381e06a573atagen2026-10-25 03:02 UTC111
80381e06a573atagen2026-10-25 03:02 UTC112
#[derive(Clone, Debug, PartialEq)]
80381e06a573atagen2026-10-25 03:02 UTC113
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC114
pub enum HistoryRepairStop {
80381e06a573atagen2026-10-25 03:02 UTC115
    Cancelled,
80381e06a573atagen2026-10-25 03:02 UTC116
    Budget,
80381e06a573atagen2026-10-25 03:02 UTC117
    HistoryUnavailable,
80381e06a573atagen2026-10-25 03:02 UTC118
    NoAnchor,
80381e06a573atagen2026-10-25 03:02 UTC119
    CursorStalled,
80381e06a573atagen2026-10-25 03:02 UTC120
}
80381e06a573atagen2026-10-25 03:02 UTC121
80381e06a573atagen2026-10-25 03:02 UTC122
#[derive(Clone, Debug, PartialEq)]
80381e06a573atagen2026-10-25 03:02 UTC123
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80381e06a573atagen2026-10-25 03:02 UTC124
pub struct HistoryRepairReport {
80381e06a573atagen2026-10-25 03:02 UTC125
    pub room_id: OwnedRoomId,
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC126
    #[cfg_attr(feature = "serde", serde(default))]
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC127
    pub gap_id: Option<OwnedTransactionId>,
80381e06a573atagen2026-10-25 03:02 UTC128
    pub requested_policy: HistoryRepairPolicy,
80381e06a573atagen2026-10-25 03:02 UTC129
    pub strategy: HistoryRepairStrategy,
80381e06a573atagen2026-10-25 03:02 UTC130
    pub coverage_duration_ms: Option<u64>,
80381e06a573atagen2026-10-25 03:02 UTC131
    pub threshold_evaluated: bool,
80381e06a573atagen2026-10-25 03:02 UTC132
    pub pages: u32,
80381e06a573atagen2026-10-25 03:02 UTC133
    pub events: u32,
80381e06a573atagen2026-10-25 03:02 UTC134
    pub phase: HistoryRepairPhase,
80381e06a573atagen2026-10-25 03:02 UTC135
    pub continuity: HistoryContinuity,
80381e06a573atagen2026-10-25 03:02 UTC136
    pub recent_available: bool,
80381e06a573atagen2026-10-25 03:02 UTC137
    pub stop: Option<HistoryRepairStop>,
80381e06a573atagen2026-10-25 03:02 UTC138
    pub failure: Option<Error>,
80381e06a573atagen2026-10-25 03:02 UTC139
}
80381e06a573atagen2026-10-25 03:02 UTC140
80381e06a573atagen2026-10-25 03:02 UTC141
#[cfg(all(test, feature = "serde"))]
80381e06a573atagen2026-10-25 03:02 UTC142
mod tests {
80381e06a573atagen2026-10-25 03:02 UTC143
    use super::*;
80381e06a573atagen2026-10-25 03:02 UTC144
    use crate::ErrorKind;
80381e06a573atagen2026-10-25 03:02 UTC145
    use ruma::room_id;
80381e06a573atagen2026-10-25 03:02 UTC146
80381e06a573atagen2026-10-25 03:02 UTC147
    #[test]
80381e06a573atagen2026-10-25 03:02 UTC148
    fn history_repair_types_round_trip_through_serde() {
80381e06a573atagen2026-10-25 03:02 UTC149
        let command = HistoryRepairCommand::Start {
80381e06a573atagen2026-10-25 03:02 UTC150
            room_id: room_id!("!room:example.org").to_owned(),
80381e06a573atagen2026-10-25 03:02 UTC151
            policy: Some(HistoryRepairPolicy::BridgeShortGaps {
80381e06a573atagen2026-10-25 03:02 UTC152
                threshold_ms: 86_400_000,
80381e06a573atagen2026-10-25 03:02 UTC153
            }),
80381e06a573atagen2026-10-25 03:02 UTC154
            budget: HistoryRepairBudget::default(),
80381e06a573atagen2026-10-25 03:02 UTC155
        };
80381e06a573atagen2026-10-25 03:02 UTC156
        let encoded_command = serde_json::to_value(&command).unwrap();
80381e06a573atagen2026-10-25 03:02 UTC157
        let decoded_command: HistoryRepairCommand =
80381e06a573atagen2026-10-25 03:02 UTC158
            serde_json::from_value(encoded_command).unwrap();
80381e06a573atagen2026-10-25 03:02 UTC159
        assert_eq!(decoded_command, command);
80381e06a573atagen2026-10-25 03:02 UTC160
80381e06a573atagen2026-10-25 03:02 UTC161
        let report = HistoryRepairReport {
c9f0fd0ee1ccatagen2026-10-25 06:16 UTC162
            gap_id: None,
80381e06a573atagen2026-10-25 03:02 UTC163
            room_id: room_id!("!room:example.org").to_owned(),
80381e06a573atagen2026-10-25 03:02 UTC164
            requested_policy: HistoryRepairPolicy::Bridge,
80381e06a573atagen2026-10-25 03:02 UTC165
            strategy: HistoryRepairStrategy::Overlap,
80381e06a573atagen2026-10-25 03:02 UTC166
            coverage_duration_ms: Some(86_400_000),
80381e06a573atagen2026-10-25 03:02 UTC167
            threshold_evaluated: false,
80381e06a573atagen2026-10-25 03:02 UTC168
            pages: 3,
80381e06a573atagen2026-10-25 03:02 UTC169
            events: 42,
80381e06a573atagen2026-10-25 03:02 UTC170
            phase: HistoryRepairPhase::Paused,
80381e06a573atagen2026-10-25 03:02 UTC171
            continuity: HistoryContinuity::Unresolved,
80381e06a573atagen2026-10-25 03:02 UTC172
            recent_available: true,
80381e06a573atagen2026-10-25 03:02 UTC173
            stop: Some(HistoryRepairStop::Budget),
80381e06a573atagen2026-10-25 03:02 UTC174
            failure: Some(Error::new(ErrorKind::Timeline, "repair failed")),
80381e06a573atagen2026-10-25 03:02 UTC175
        };
80381e06a573atagen2026-10-25 03:02 UTC176
        let encoded_report = serde_json::to_value(&report).unwrap();
80381e06a573atagen2026-10-25 03:02 UTC177
        let decoded_report: HistoryRepairReport = serde_json::from_value(encoded_report).unwrap();
80381e06a573atagen2026-10-25 03:02 UTC178
        assert_eq!(decoded_report, report);
80381e06a573atagen2026-10-25 03:02 UTC179
    }
80381e06a573atagen2026-10-25 03:02 UTC180
}