atagen

macltok

public
Star0
Watch0
2c13c8db61741baf208b9c98b78c4a9e97d1fe61
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git
src/repair_model.rsRust180 lines4.9 KB
1
use ruma::{OwnedEventId, OwnedRoomId, OwnedTransactionId};
2
3
#[cfg(feature = "serde")]
4
use serde::{Deserialize, Serialize};
5
6
use crate::Error;
7
8
#[derive(Clone, Debug, PartialEq, Eq)]
9
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10
pub enum HistoryRepairPolicy {
11
    StartRecent,
12
    Bridge,
13
    BridgeShortGaps { threshold_ms: u64 },
14
}
15
16
impl Default for HistoryRepairPolicy {
17
    fn default() -> Self {
18
        Self::StartRecent
19
    }
20
}
21
22
#[derive(Clone, Debug, PartialEq)]
23
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24
pub struct HistoryRepairBudget {
25
    pub max_pages: u16,
26
    pub max_events: u32,
27
    pub max_duration_ms: u64,
28
}
29
30
impl Default for HistoryRepairBudget {
31
    fn default() -> Self {
32
        Self {
33
            max_pages: 4,
34
            max_events: 200,
35
            max_duration_ms: 15_000,
36
        }
37
    }
38
}
39
40
#[derive(Clone, Debug, PartialEq)]
41
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42
pub enum HistoryRepairCommand {
43
    Start {
44
        room_id: OwnedRoomId,
45
        policy: Option<HistoryRepairPolicy>,
46
        budget: HistoryRepairBudget,
47
    },
48
    Continue {
49
        room_id: OwnedRoomId,
50
        budget: HistoryRepairBudget,
51
    },
52
    Cancel {
53
        room_id: OwnedRoomId,
54
    },
55
    StartRecent {
56
        room_id: OwnedRoomId,
57
    },
58
    FillGap {
59
        room_id: OwnedRoomId,
60
        gap_id: OwnedTransactionId,
61
    },
62
    GetPolicy,
63
    SetPolicy(HistoryRepairPolicy),
64
}
65
66
#[derive(Clone, Debug, PartialEq, Eq)]
67
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
68
pub struct HistoryGap {
69
    pub id: OwnedTransactionId,
70
    pub older_boundary: Option<OwnedEventId>,
71
    pub newer_boundary: Option<OwnedEventId>,
72
    pub lifecycle: HistoryGapLifecycle,
73
    pub continuity: HistoryContinuity,
74
    pub failure: Option<String>,
75
}
76
77
#[derive(Clone, Debug, PartialEq, Eq)]
78
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
79
pub enum HistoryGapLifecycle {
80
    Idle,
81
    Fetching,
82
    Paused,
83
    Failed,
84
    Unavailable,
85
}
86
87
#[derive(Clone, Debug, PartialEq, Eq)]
88
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
89
pub enum HistoryRepairStrategy {
90
    Recent,
91
    Overlap,
92
    Bridge,
93
}
94
95
#[derive(Clone, Debug, PartialEq, Eq)]
96
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
97
pub enum HistoryContinuity {
98
    Unresolved,
99
    Verified,
100
    AccessibleStart,
101
}
102
103
#[derive(Clone, Debug, PartialEq)]
104
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
105
pub enum HistoryRepairPhase {
106
    FetchingRecent,
107
    Bridging,
108
    Ready,
109
    Paused,
110
}
111
112
#[derive(Clone, Debug, PartialEq)]
113
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
114
pub enum HistoryRepairStop {
115
    Cancelled,
116
    Budget,
117
    HistoryUnavailable,
118
    NoAnchor,
119
    CursorStalled,
120
}
121
122
#[derive(Clone, Debug, PartialEq)]
123
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
124
pub struct HistoryRepairReport {
125
    pub room_id: OwnedRoomId,
126
    #[cfg_attr(feature = "serde", serde(default))]
127
    pub gap_id: Option<OwnedTransactionId>,
128
    pub requested_policy: HistoryRepairPolicy,
129
    pub strategy: HistoryRepairStrategy,
130
    pub coverage_duration_ms: Option<u64>,
131
    pub threshold_evaluated: bool,
132
    pub pages: u32,
133
    pub events: u32,
134
    pub phase: HistoryRepairPhase,
135
    pub continuity: HistoryContinuity,
136
    pub recent_available: bool,
137
    pub stop: Option<HistoryRepairStop>,
138
    pub failure: Option<Error>,
139
}
140
141
#[cfg(all(test, feature = "serde"))]
142
mod tests {
143
    use super::*;
144
    use crate::ErrorKind;
145
    use ruma::room_id;
146
147
    #[test]
148
    fn history_repair_types_round_trip_through_serde() {
149
        let command = HistoryRepairCommand::Start {
150
            room_id: room_id!("!room:example.org").to_owned(),
151
            policy: Some(HistoryRepairPolicy::BridgeShortGaps {
152
                threshold_ms: 86_400_000,
153
            }),
154
            budget: HistoryRepairBudget::default(),
155
        };
156
        let encoded_command = serde_json::to_value(&command).unwrap();
157
        let decoded_command: HistoryRepairCommand =
158
            serde_json::from_value(encoded_command).unwrap();
159
        assert_eq!(decoded_command, command);
160
161
        let report = HistoryRepairReport {
162
            gap_id: None,
163
            room_id: room_id!("!room:example.org").to_owned(),
164
            requested_policy: HistoryRepairPolicy::Bridge,
165
            strategy: HistoryRepairStrategy::Overlap,
166
            coverage_duration_ms: Some(86_400_000),
167
            threshold_evaluated: false,
168
            pages: 3,
169
            events: 42,
170
            phase: HistoryRepairPhase::Paused,
171
            continuity: HistoryContinuity::Unresolved,
172
            recent_available: true,
173
            stop: Some(HistoryRepairStop::Budget),
174
            failure: Some(Error::new(ErrorKind::Timeline, "repair failed")),
175
        };
176
        let encoded_report = serde_json::to_value(&report).unwrap();
177
        let decoded_report: HistoryRepairReport = serde_json::from_value(encoded_report).unwrap();
178
        assert_eq!(decoded_report, report);
179
    }
180
}