diff options
Diffstat (limited to 'docs/explanation/announcements-purgatory-implementation.md')
| -rw-r--r-- | docs/explanation/announcements-purgatory-implementation.md | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/docs/explanation/announcements-purgatory-implementation.md b/docs/explanation/announcements-purgatory-implementation.md index d5b8698..263c253 100644 --- a/docs/explanation/announcements-purgatory-implementation.md +++ b/docs/explanation/announcements-purgatory-implementation.md | |||
| @@ -204,21 +204,22 @@ impl Purgatory { | |||
| 204 | .collect() | 204 | .collect() |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | /// Transition to soft-expired state | 207 | /// Transition to soft-expired state (protocol's 30min expiry reached) |
| 208 | pub fn soft_expire_announcement( | 208 | pub fn soft_expire_announcement( |
| 209 | &self, | 209 | &self, |
| 210 | key: &(PublicKey, String), | 210 | key: &(PublicKey, String), |
| 211 | ) -> Option<PathBuf> { | 211 | ) -> Option<PathBuf> { |
| 212 | if let Some(mut entry) = self.announcement_purgatory.get_mut(key) { | 212 | if let Some(mut entry) = self.announcement_purgatory.get_mut(key) { |
| 213 | entry.soft_expired = true; | 213 | entry.soft_expired = true; |
| 214 | entry.expires_at = Instant::now() + SOFT_EXPIRY_DURATION; // e.g., 24h | 214 | entry.expires_at = Instant::now() + SOFT_EXPIRY_DURATION; // e.g., 24h extended retention |
| 215 | Some(entry.repo_path.clone()) // Return path for bare repo deletion | 215 | Some(entry.repo_path.clone()) // Return path for bare repo deletion |
| 216 | } else { | 216 | } else { |
| 217 | None | 217 | None |
| 218 | } | 218 | } |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | /// Revive soft-expired announcement (caller must recreate bare repo) | 221 | /// Revive soft-expired announcement when state event arrives |
| 222 | /// (caller must recreate bare repo) | ||
| 222 | pub fn revive_announcement( | 223 | pub fn revive_announcement( |
| 223 | &self, | 224 | &self, |
| 224 | key: &(PublicKey, String), | 225 | key: &(PublicKey, String), |
| @@ -226,7 +227,7 @@ impl Purgatory { | |||
| 226 | if let Some(mut entry) = self.announcement_purgatory.get_mut(key) { | 227 | if let Some(mut entry) = self.announcement_purgatory.get_mut(key) { |
| 227 | if entry.soft_expired { | 228 | if entry.soft_expired { |
| 228 | entry.soft_expired = false; | 229 | entry.soft_expired = false; |
| 229 | entry.expires_at = Instant::now() + ACTIVE_EXPIRY_DURATION; | 230 | entry.expires_at = Instant::now() + ACTIVE_EXPIRY_DURATION; // Reset 30min protocol timer |
| 230 | return Some(entry.repo_path.clone()); // Caller recreates bare repo | 231 | return Some(entry.repo_path.clone()); // Caller recreates bare repo |
| 231 | } | 232 | } |
| 232 | } | 233 | } |
| @@ -270,9 +271,11 @@ When a state event arrives for a soft-expired announcement, the state policy mus | |||
| 270 | 1. Check purgatory for a matching announcement (in addition to DB) | 271 | 1. Check purgatory for a matching announcement (in addition to DB) |
| 271 | 2. Validate authorization against the purgatory announcement | 272 | 2. Validate authorization against the purgatory announcement |
| 272 | 3. If soft-expired, call `revive_announcement()` and recreate the bare repo | 273 | 3. If soft-expired, call `revive_announcement()` and recreate the bare repo |
| 273 | 4. Extend the announcement's expiry | 274 | 4. Extend the announcement's expiry (reset the 30-minute protocol timer) |
| 274 | 5. Route the state event to state purgatory | 275 | 5. Route the state event to state purgatory |
| 275 | 276 | ||
| 277 | **Why revival is necessary:** Without soft expiry + revival, late-arriving state events would either be permanently rejected (if we added the announcement to `failed_events`) or cause constant re-syncing of the announcement event. Revival allows us to respect the protocol's 30-minute expiry while still handling delayed state events gracefully. | ||
| 278 | |||
| 276 | The exact integration will depend on the current structure of `StatePolicy::process_state_event()` - see implementation phase for details. | 279 | The exact integration will depend on the current structure of `StatePolicy::process_state_event()` - see implementation phase for details. |
| 277 | 280 | ||
| 278 | ## File Change Summary | 281 | ## File Change Summary |