7171 } )
7272}
7373
74- fn clients_line < I > ( x : & ' static str ) -> impl Parser < I , Output = u64 >
74+ fn clients_line < I > ( x : & ' static str ) -> impl Parser < I , Output = ( u64 , Option < u64 > ) >
7575where
7676 I : Stream < Token = char > ,
7777 I :: Error : ParseError < I :: Token , I :: Range , I :: Position > ,
@@ -83,15 +83,18 @@ where
8383 optional ( ( token ( '/' ) , digits ( ) ) ) ,
8484 optional ( newline ( ) . map ( drop) . or ( eof ( ) ) ) ,
8585 )
86- . map ( |( _, _, x, _ , _) : ( _ , _ , u64 , _ , _ ) | x )
86+ . map ( |( _, _, x, y , _) : ( _ , _ , u64 , Option < ( _ , u64 ) > , _ ) | ( x , y . map ( | ( _ , v ) | v ) ) )
8787}
8888
8989#[ derive( Debug ) ]
9090enum RecoveryStat {
91- Status ( RecoveryStatus ) ,
9291 Completed ( u64 ) ,
9392 Connected ( u64 ) ,
9493 Evicted ( u64 ) ,
94+ RecoveryDuration ( u64 ) ,
95+ Status ( RecoveryStatus ) ,
96+ TimeRemaining ( u64 ) ,
97+ Total ( Option < u64 > ) ,
9598}
9699
97100pub struct StatName ( pub String ) ;
@@ -105,6 +108,19 @@ where
105108 many1 ( alpha_num ( ) . or ( one_of ( "_-" . chars ( ) ) ) ) . map ( StatName )
106109}
107110
111+ fn simple_client_stat < I > (
112+ name : & ' static str ,
113+ constructor : fn ( u64 ) -> RecoveryStat ,
114+ ) -> impl Parser < I , Output = Vec < RecoveryStat > >
115+ where
116+ I : Stream < Token = char > ,
117+ I :: Error : ParseError < I :: Token , I :: Range , I :: Position > ,
118+ {
119+ clients_line ( name)
120+ . skip ( optional ( newline ( ) ) )
121+ . map ( move |( x, _) | vec ! [ constructor( x) ] )
122+ }
123+
108124fn target_recovery_stats < I > ( ) -> impl Parser < I , Output = Vec < RecoveryStat > >
109125where
110126 I : Stream < Token = char > ,
@@ -113,22 +129,22 @@ where
113129 many ( choice ( (
114130 status_line ( )
115131 . skip ( optional ( newline ( ) ) )
116- . map ( RecoveryStat :: Status )
117- . map ( Some ) ,
118- clients_line ( "completed_clients" )
119- . skip ( optional ( newline ( ) ) )
120- . map ( RecoveryStat :: Completed )
121- . map ( Some ) ,
132+ . map ( |x| vec ! [ RecoveryStat :: Status ( x) ] ) ,
133+ simple_client_stat ( "recovery_duration" , RecoveryStat :: RecoveryDuration ) ,
134+ simple_client_stat ( "completed_clients" , RecoveryStat :: Completed ) ,
135+ simple_client_stat ( "time_remaining" , RecoveryStat :: TimeRemaining ) ,
136+ simple_client_stat ( "evicted_clients" , RecoveryStat :: Evicted ) ,
122137 clients_line ( "connected_clients" )
123138 . skip ( optional ( newline ( ) ) )
124- . map ( RecoveryStat :: Connected )
125- . map ( Some ) ,
126- clients_line ( "evicted_clients" )
127- . skip ( optional ( newline ( ) ) )
128- . map ( RecoveryStat :: Evicted )
129- . map ( Some ) ,
139+ . map ( |( x, y) | {
140+ let mut stats = vec ! [ RecoveryStat :: Connected ( x) ] ;
141+ if let Some ( total) = y {
142+ stats. push ( RecoveryStat :: Total ( Some ( total) ) ) ;
143+ }
144+ stats
145+ } ) ,
130146 // This will ignore line/field we don't care
131- attempt ( ( stat_name ( ) , token ( ':' ) , till_newline ( ) . skip ( newline ( ) ) ) ) . map ( |_| None ) ,
147+ attempt ( ( stat_name ( ) , token ( ':' ) , till_newline ( ) . skip ( newline ( ) ) ) ) . map ( |_| vec ! [ ] ) ,
132148 ) ) )
133149 . map ( |xs : Vec < _ > | xs. into_iter ( ) . flatten ( ) . collect ( ) )
134150}
@@ -176,6 +192,28 @@ where
176192 value : * value,
177193 } )
178194 }
195+ RecoveryStat :: RecoveryDuration ( value) => {
196+ TargetStats :: RecoveryDuration ( TargetStat {
197+ kind,
198+ param : param. clone ( ) ,
199+ target : target. clone ( ) ,
200+ value : * value,
201+ } )
202+ }
203+ RecoveryStat :: TimeRemaining ( value) => {
204+ TargetStats :: RecoveryTimeRemaining ( TargetStat {
205+ kind,
206+ param : param. clone ( ) ,
207+ target : target. clone ( ) ,
208+ value : * value,
209+ } )
210+ }
211+ RecoveryStat :: Total ( value) => TargetStats :: RecoveryTotalClients ( TargetStat {
212+ kind,
213+ param : param. clone ( ) ,
214+ target : target. clone ( ) ,
215+ value : value. unwrap_or ( 0 ) ,
216+ } ) ,
179217 } )
180218 . collect ( )
181219 } )
@@ -186,19 +224,17 @@ where
186224 I : Stream < Token = char > ,
187225 I :: Error : ParseError < I :: Token , I :: Range , I :: Position > ,
188226{
189- many (
190- (
191- target_status ( ) ,
192- skip_until ( attempt ( ost_or_mdt ( ) . map ( drop) ) . or ( eof ( ) ) ) ,
193- )
194- . map ( |( x, _) | x. into_iter ( ) . map ( Record :: Target ) . collect ( ) ) ,
227+ (
228+ target_status ( ) ,
229+ skip_until ( attempt ( ost_or_mdt ( ) . map ( drop) ) . or ( eof ( ) ) ) ,
195230 )
196- . map ( |x : Vec < Vec < Record > > | x. into_iter ( ) . flatten ( ) . collect ( ) )
231+ . map ( |( x , _ ) | x. into_iter ( ) . map ( Record :: Target ) . collect ( ) )
197232}
198233
199234#[ cfg( test) ]
200235mod tests {
201- use crate :: recovery_status_parser:: { clients_line, parse, target_recovery_stats} ;
236+ use crate :: parser:: parse;
237+ use crate :: recovery_status_parser:: { clients_line, target_recovery_stats} ;
202238 use combine:: { Parser , parser:: EasyParser , stream:: position} ;
203239
204240 #[ test]
@@ -238,11 +274,11 @@ mod tests {
238274 #[ test]
239275 fn test_clients_line ( ) {
240276 let result = clients_line ( "completed_clients" ) . parse ( "completed_clients: 3/7\n " ) ;
241- assert_eq ! ( result, Ok ( ( 3 , "" ) ) ) ;
277+ assert_eq ! ( result, Ok ( ( ( 3 , Some ( 7 ) ) , "" ) ) ) ;
242278 let result = clients_line ( "connected_clients" ) . parse ( "connected_clients: 3/7\n " ) ;
243- assert_eq ! ( result, Ok ( ( 3 , "" ) ) ) ;
279+ assert_eq ! ( result, Ok ( ( ( 3 , Some ( 7 ) ) , "" ) ) ) ;
244280 let result = clients_line ( "completed_clients" ) . parse ( "completed_clients: 3\n " ) ;
245- assert_eq ! ( result, Ok ( ( 3 , "" ) ) ) ;
281+ assert_eq ! ( result, Ok ( ( ( 3 , None ) , "" ) ) ) ;
246282 }
247283
248284 #[ test]
@@ -259,7 +295,19 @@ IR: ENABLED
259295
260296 let ( records, _) : ( Vec < _ > , _ ) = target_recovery_stats ( ) . parse ( x) . unwrap ( ) ;
261297
262- insta:: assert_debug_snapshot!( records) ;
298+ insta:: assert_debug_snapshot!( records, @r"
299+ [
300+ Status(
301+ Complete,
302+ ),
303+ RecoveryDuration(
304+ 150,
305+ ),
306+ Completed(
307+ 4,
308+ ),
309+ ]
310+ " ) ;
263311 }
264312
265313 #[ test]
@@ -275,6 +323,26 @@ completed_clients: 3
275323
276324 let ( records, _) : ( Vec < _ > , _ ) = target_recovery_stats ( ) . parse ( x) . unwrap ( ) ;
277325
278- insta:: assert_debug_snapshot!( records) ;
326+ insta:: assert_debug_snapshot!( records, @r"
327+ [
328+ Status(
329+ Recovering,
330+ ),
331+ TimeRemaining(
332+ 119,
333+ ),
334+ Connected(
335+ 3,
336+ ),
337+ Total(
338+ Some(
339+ 7,
340+ ),
341+ ),
342+ Completed(
343+ 3,
344+ ),
345+ ]
346+ " ) ;
279347 }
280348}
0 commit comments