|
1 | 1 | use async_trait::async_trait; |
2 | | -use chrono::{DateTime, Utc}; |
| 2 | +use chrono::{DateTime, Duration, Utc}; |
3 | 3 | use futures::TryStreamExt; |
4 | | -use mongodb::bson::Binary; |
5 | 4 | use mongodb::bson::doc; |
6 | 5 | use mongodb::bson::oid::ObjectId; |
7 | 6 | use mongodb::bson::spec::BinarySubtype; |
| 7 | +use mongodb::bson::{Binary, DateTime as BsonDateTime}; |
8 | 8 | use mongodb::options::{FindOneOptions, IndexOptions, ReplaceOptions}; |
9 | 9 | use mongodb::{Collection, Database, IndexModel}; |
10 | 10 | use serde::{Deserialize, Serialize}; |
@@ -100,6 +100,53 @@ impl MongoDbMessageStore { |
100 | 100 |
|
101 | 101 | Ok(initial_meta) |
102 | 102 | } |
| 103 | + |
| 104 | + /// Deletes sequences older than the specified age, along with their associated messages. |
| 105 | + /// |
| 106 | + /// Returns the number of deleted sequences. |
| 107 | + pub async fn cleanup_older_than(&self, age: Duration) -> Result<u64> { |
| 108 | + let cutoff = BsonDateTime::from_millis((Utc::now() - age).timestamp_millis()); |
| 109 | + |
| 110 | + // Find old sequence IDs (excluding current sequence) |
| 111 | + let filter = doc! { |
| 112 | + "meta": true, |
| 113 | + "creation_time": { "$lt": cutoff }, |
| 114 | + "_id": { "$ne": self.current_sequence.object_id } |
| 115 | + }; |
| 116 | + let mut cursor = self |
| 117 | + .meta_collection |
| 118 | + .find(filter) |
| 119 | + .await |
| 120 | + .map_err(|e| StoreError::Cleanup(e.into()))?; |
| 121 | + |
| 122 | + let mut old_sequence_ids = Vec::new(); |
| 123 | + while let Some(meta) = cursor |
| 124 | + .try_next() |
| 125 | + .await |
| 126 | + .map_err(|e| StoreError::Cleanup(e.into()))? |
| 127 | + { |
| 128 | + old_sequence_ids.push(meta.object_id); |
| 129 | + } |
| 130 | + |
| 131 | + if old_sequence_ids.is_empty() { |
| 132 | + return Ok(0); |
| 133 | + } |
| 134 | + |
| 135 | + // Delete messages first to avoid orphaned meta documents |
| 136 | + self.message_collection |
| 137 | + .delete_many(doc! { "sequence_id": { "$in": &old_sequence_ids } }) |
| 138 | + .await |
| 139 | + .map_err(|e| StoreError::Cleanup(e.into()))?; |
| 140 | + |
| 141 | + // Delete sequence metas |
| 142 | + let result = self |
| 143 | + .meta_collection |
| 144 | + .delete_many(doc! { "_id": { "$in": &old_sequence_ids } }) |
| 145 | + .await |
| 146 | + .map_err(|e| StoreError::Cleanup(e.into()))?; |
| 147 | + |
| 148 | + Ok(result.deleted_count) |
| 149 | + } |
103 | 150 | } |
104 | 151 |
|
105 | 152 | #[async_trait] |
|
0 commit comments