@@ -30,13 +30,23 @@ pub struct CaptureObserver {
3030
3131impl TrafficObserver for CaptureObserver {
3232 fn observe ( & self , direction : TrafficDirection , data : & [ u8 ] ) {
33- let already = self . captured . load ( Ordering :: Relaxed ) ;
34- if already >= self . max_bytes {
35- self . truncated . store ( true , Ordering :: Relaxed ) ;
36- return ;
37- }
38- let remaining = ( self . max_bytes - already) as usize ;
39- let length = remaining. min ( data. len ( ) ) ;
33+ let mut already = self . captured . load ( Ordering :: Relaxed ) ;
34+ let length = loop {
35+ if already >= self . max_bytes {
36+ self . truncated . store ( true , Ordering :: Relaxed ) ;
37+ return ;
38+ }
39+ let length = ( ( self . max_bytes - already) as usize ) . min ( data. len ( ) ) ;
40+ match self . captured . compare_exchange_weak (
41+ already,
42+ already + length as u64 ,
43+ Ordering :: Relaxed ,
44+ Ordering :: Relaxed ,
45+ ) {
46+ Ok ( _) => break length,
47+ Err ( current) => already = current,
48+ }
49+ } ;
4050 if length < data. len ( ) {
4151 self . truncated . store ( true , Ordering :: Relaxed ) ;
4252 }
@@ -46,8 +56,9 @@ impl TrafficObserver for CaptureObserver {
4656 . try_send ( CaptureMessage :: Packet ( direction, packet, SystemTime :: now ( ) ) )
4757 . is_ok ( )
4858 {
49- self . captured . fetch_add ( length as u64 , Ordering :: Relaxed ) ;
59+ // The byte reservation above is now committed.
5060 } else {
61+ self . captured . fetch_sub ( length as u64 , Ordering :: Relaxed ) ;
5162 self . truncated . store ( true , Ordering :: Relaxed ) ;
5263 }
5364 }
@@ -266,12 +277,14 @@ pub fn spawn_retention_cleanup(root: PathBuf, retention_days: u64, max_total_byt
266277 loop {
267278 interval. tick ( ) . await ;
268279 let root = root. clone ( ) ;
269- if let Err ( err ) = tokio:: task:: spawn_blocking ( move || {
280+ match tokio:: task:: spawn_blocking ( move || {
270281 cleanup_capture_files ( & root, retention_days, max_total_bytes)
271282 } )
272283 . await
273284 {
274- error ! ( "capture retention worker failed: {err}" ) ;
285+ Ok ( Ok ( ( ) ) ) => { }
286+ Ok ( Err ( err) ) => error ! ( "capture retention cleanup failed: {err}" ) ,
287+ Err ( err) => error ! ( "capture retention worker failed: {err}" ) ,
275288 }
276289 }
277290 } ) ;
0 commit comments