@@ -1130,60 +1130,91 @@ where
11301130 queue. drain ( ..n) . collect :: < Vec < _ > > ( )
11311131 } ;
11321132
1133- let mut completed = Vec :: new ( ) ;
1134- for write in pending {
1133+ // Phase 1: Collect all batch entries
1134+ let mut batch_entries = Vec :: with_capacity ( pending. len ( ) ) ;
1135+ let mut stale_cleanups = Vec :: new ( ) ;
1136+
1137+ for ( i, write) in pending. iter ( ) . enumerate ( ) {
11351138 match write {
11361139 PendingWrite :: FullMonitor {
11371140 monitor_key,
11381141 monitor_bytes,
1139- completion,
11401142 stale_update_cleanup,
1143+ ..
11411144 } => {
1142- self . 0
1143- . kv_store
1144- . write (
1145- CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE ,
1146- CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE ,
1147- & monitor_key,
1148- monitor_bytes,
1149- )
1150- . await ?;
1151- completed. push ( completion) ;
1152-
1153- // Clean up stale updates after successfully writing a full monitor
1145+ batch_entries. push ( BatchWriteEntry :: new (
1146+ CHANNEL_MONITOR_PERSISTENCE_PRIMARY_NAMESPACE ,
1147+ CHANNEL_MONITOR_PERSISTENCE_SECONDARY_NAMESPACE ,
1148+ monitor_key. clone ( ) ,
1149+ monitor_bytes. clone ( ) ,
1150+ ) ) ;
11541151 if let Some ( ( start, end) ) = stale_update_cleanup {
1155- for update_id in start..end {
1156- let update_name = UpdateName :: from ( update_id) ;
1157- // Lazy delete - ignore errors as this is just cleanup
1158- let _ = self
1159- . 0
1160- . kv_store
1161- . remove (
1162- CHANNEL_MONITOR_UPDATE_PERSISTENCE_PRIMARY_NAMESPACE ,
1163- & monitor_key,
1164- update_name. as_str ( ) ,
1165- true ,
1166- )
1167- . await ;
1168- }
1152+ stale_cleanups. push ( ( i, monitor_key. clone ( ) , * start, * end) ) ;
11691153 }
11701154 } ,
1171- PendingWrite :: Update { monitor_key, update_key, update_bytes, completion } => {
1172- self . 0
1155+ PendingWrite :: Update { monitor_key, update_key, update_bytes, .. } => {
1156+ batch_entries. push ( BatchWriteEntry :: new (
1157+ CHANNEL_MONITOR_UPDATE_PERSISTENCE_PRIMARY_NAMESPACE ,
1158+ monitor_key. clone ( ) ,
1159+ update_key. clone ( ) ,
1160+ update_bytes. clone ( ) ,
1161+ ) ) ;
1162+ } ,
1163+ }
1164+ }
1165+
1166+ // Phase 2: Execute batch write
1167+ let successful_writes = if !batch_entries. is_empty ( ) {
1168+ let result = self . 0 . kv_store . write_batch ( batch_entries) . await ;
1169+ if let Some ( err) = result. error {
1170+ // Re-queue failed and subsequent writes
1171+ let failed_writes =
1172+ pending. into_iter ( ) . skip ( result. successful_writes ) . collect :: < Vec < _ > > ( ) ;
1173+ if !failed_writes. is_empty ( ) {
1174+ let mut queue = self . 0 . pending_writes . lock ( ) . unwrap ( ) ;
1175+ // Prepend failed writes back to the front of the queue
1176+ for write in failed_writes. into_iter ( ) . rev ( ) {
1177+ queue. insert ( 0 , write) ;
1178+ }
1179+ }
1180+ return Err ( err) ;
1181+ }
1182+ result. successful_writes
1183+ } else {
1184+ 0
1185+ } ;
1186+
1187+ // Phase 3: Cleanup stale updates (only for successfully written monitors)
1188+ for ( i, monitor_key, start, end) in stale_cleanups {
1189+ if i < successful_writes {
1190+ for update_id in start..end {
1191+ let update_name = UpdateName :: from ( update_id) ;
1192+ // Lazy delete - ignore errors as this is just cleanup
1193+ let _ = self
1194+ . 0
11731195 . kv_store
1174- . write (
1196+ . remove (
11751197 CHANNEL_MONITOR_UPDATE_PERSISTENCE_PRIMARY_NAMESPACE ,
11761198 & monitor_key,
1177- & update_key ,
1178- update_bytes ,
1199+ update_name . as_str ( ) ,
1200+ true ,
11791201 )
1180- . await ?;
1181- completed. push ( completion) ;
1182- } ,
1202+ . await ;
1203+ }
11831204 }
11841205 }
11851206
1186- Ok ( completed)
1207+ // Phase 4: Return completions for successful writes only
1208+ let completions = pending
1209+ . into_iter ( )
1210+ . take ( successful_writes)
1211+ . map ( |write| match write {
1212+ PendingWrite :: FullMonitor { completion, .. } => completion,
1213+ PendingWrite :: Update { completion, .. } => completion,
1214+ } )
1215+ . collect ( ) ;
1216+
1217+ Ok ( completions)
11871218 }
11881219}
11891220
0 commit comments