1010//
1111// SPDX-License-Identifier: Apache-2.0
1212// *******************************************************************************
13+ use crate :: common:: { HasEvalHandle , MonitorEvalHandle , MonitorEvaluationError , MonitorEvaluator } ;
1314use crate :: deadline:: common:: { DeadlineTemplate , StateIndex } ;
1415use crate :: deadline:: deadline_state:: { DeadlineState , DeadlineStateSnapshot } ;
1516use crate :: log:: { error, warn, ScoreDebug } ;
@@ -23,7 +24,7 @@ use std::time::Instant;
2324
2425/// Deadline evaluation errors.
2526#[ derive( Debug , PartialEq , Eq , Clone , Copy , Hash , ScoreDebug ) ]
26- pub ( crate ) enum DeadlineEvalError {
27+ pub ( crate ) enum DeadlineEvaluationError {
2728 /// Finished too early.
2829 TooEarly ,
2930 /// Finished too late.
@@ -69,12 +70,9 @@ impl DeadlineMonitorBuilder {
6970 }
7071
7172 /// Builds the DeadlineMonitor with the configured deadlines.
72- pub ( crate ) fn build (
73- self ,
74- monitor_tag : MonitorTag ,
75- _allocator : & ProtectedMemoryAllocator ,
76- ) -> Arc < DeadlineMonitorInner > {
77- Arc :: new ( DeadlineMonitorInner :: new ( monitor_tag, self . deadlines ) )
73+ pub ( crate ) fn build ( self , monitor_tag : MonitorTag , _allocator : & ProtectedMemoryAllocator ) -> DeadlineMonitor {
74+ let inner = Arc :: new ( DeadlineMonitorInner :: new ( monitor_tag, self . deadlines ) ) ;
75+ DeadlineMonitor :: new ( inner)
7876 }
7977
8078 // Used by FFI and config parsing code which prefer not to move builder instance
@@ -90,7 +88,7 @@ pub struct DeadlineMonitor {
9088
9189impl DeadlineMonitor {
9290 /// Create a new [`DeadlineMonitor`] instance.
93- pub ( crate ) fn new ( inner : Arc < DeadlineMonitorInner > ) -> Self {
91+ fn new ( inner : Arc < DeadlineMonitorInner > ) -> Self {
9492 Self { inner }
9593 }
9694
@@ -104,6 +102,12 @@ impl DeadlineMonitor {
104102 }
105103}
106104
105+ impl HasEvalHandle for DeadlineMonitor {
106+ fn get_eval_handle ( & self ) -> MonitorEvalHandle {
107+ MonitorEvalHandle :: new ( Arc :: clone ( & self . inner ) )
108+ }
109+ }
110+
107111/// Represents a deadline that can be started and stopped.
108112pub struct Deadline {
109113 range : TimeRange ,
@@ -191,7 +195,7 @@ impl Deadline {
191195
192196 let expected = current. timestamp_ms ( ) ;
193197 if expected < now {
194- possible_err = ( Some ( DeadlineEvalError :: TooLate ) , now - expected) ;
198+ possible_err = ( Some ( DeadlineEvaluationError :: TooLate ) , now - expected) ;
195199 return None ; // Deadline missed, let state as is for BG thread to report
196200 }
197201
@@ -202,18 +206,18 @@ impl Deadline {
202206 // Finished too early, leave it for reporting by BG thread
203207
204208 current. set_underrun ( ) ;
205- possible_err = ( Some ( DeadlineEvalError :: TooEarly ) , earliest_time - now) ;
209+ possible_err = ( Some ( DeadlineEvaluationError :: TooEarly ) , earliest_time - now) ;
206210 return Some ( current) ;
207211 }
208212
209213 Some ( DeadlineStateSnapshot :: default ( ) ) // Reset to stopped state as all fine
210214 } ) ;
211215
212216 match possible_err {
213- ( Some ( DeadlineEvalError :: TooEarly ) , val) => {
217+ ( Some ( DeadlineEvaluationError :: TooEarly ) , val) => {
214218 error ! ( "Deadline {:?} stopped too early by {} ms" , self . deadline_tag, val) ;
215219 } ,
216- ( Some ( DeadlineEvalError :: TooLate ) , val) => {
220+ ( Some ( DeadlineEvaluationError :: TooLate ) , val) => {
217221 error ! ( "Deadline {:?} stopped too late by {} ms" , self . deadline_tag, val) ;
218222 } ,
219223 ( None , _) => { } ,
@@ -239,7 +243,7 @@ impl Drop for Deadline {
239243 }
240244}
241245
242- pub ( crate ) struct DeadlineMonitorInner {
246+ struct DeadlineMonitorInner {
243247 /// Tag of this monitor.
244248 monitor_tag : MonitorTag ,
245249
@@ -255,6 +259,39 @@ pub(crate) struct DeadlineMonitorInner {
255259 active_deadlines : Arc < [ ( DeadlineTag , DeadlineState ) ] > ,
256260}
257261
262+ impl MonitorEvaluator for DeadlineMonitorInner {
263+ fn evaluate ( & self , on_error : & mut dyn FnMut ( & MonitorTag , MonitorEvaluationError ) ) {
264+ for ( deadline_tag, deadline) in self . active_deadlines . iter ( ) {
265+ let snapshot = deadline. snapshot ( ) ;
266+ if snapshot. is_underrun ( ) {
267+ // Deadline finished too early, report
268+ warn ! ( "Deadline ({:?}) finished too early!" , deadline_tag) ;
269+
270+ // Here we would normally report the underrun to the monitoring system
271+ on_error ( & self . monitor_tag , DeadlineEvaluationError :: TooEarly . into ( ) ) ;
272+ } else if snapshot. is_running ( ) {
273+ debug_assert ! (
274+ snapshot. is_stopped( ) ,
275+ "Deadline snapshot cannot be both running and stopped"
276+ ) ;
277+
278+ let now = self . now ( ) ;
279+ let expected = snapshot. timestamp_ms ( ) ;
280+ if now > expected {
281+ // Deadline missed, report
282+ warn ! (
283+ "Deadline ({:?}) missed! Expected: {}, now: {}" ,
284+ deadline_tag, expected, now
285+ ) ;
286+
287+ // Here we would normally report the missed deadline to the monitoring system
288+ on_error ( & self . monitor_tag , DeadlineEvaluationError :: TooLate . into ( ) ) ;
289+ }
290+ }
291+ }
292+ }
293+ }
294+
258295impl DeadlineMonitorInner {
259296 fn new ( monitor_tag : MonitorTag , deadlines : HashMap < DeadlineTag , TimeRange > ) -> Self {
260297 let mut active_deadlines = vec ! [ ] ;
@@ -307,37 +344,6 @@ impl DeadlineMonitorInner {
307344 // We still have a room up to 60bits timestamp if needed in future
308345 u32:: try_from ( duration. as_millis ( ) ) . expect ( "Monitor running for too long" )
309346 }
310-
311- pub ( crate ) fn evaluate ( & self , on_error : & mut dyn FnMut ( & MonitorTag , DeadlineEvalError ) ) {
312- for ( deadline_tag, deadline) in self . active_deadlines . iter ( ) {
313- let snapshot = deadline. snapshot ( ) ;
314- if snapshot. is_underrun ( ) {
315- // Deadline finished too early, report
316- warn ! ( "Deadline ({:?}) finished too early!" , deadline_tag) ;
317-
318- // Here we would normally report the underrun to the monitoring system
319- on_error ( & self . monitor_tag , DeadlineEvalError :: TooEarly ) ;
320- } else if snapshot. is_running ( ) {
321- debug_assert ! (
322- snapshot. is_stopped( ) ,
323- "Deadline snapshot cannot be both running and stopped"
324- ) ;
325-
326- let now = self . now ( ) ;
327- let expected = snapshot. timestamp_ms ( ) ;
328- if now > expected {
329- // Deadline missed, report
330- warn ! (
331- "Deadline ({:?}) missed! Expected: {}, now: {}" ,
332- deadline_tag, expected, now
333- ) ;
334-
335- // Here we would normally report the missed deadline to the monitoring system
336- on_error ( & self . monitor_tag , DeadlineEvalError :: TooLate ) ;
337- }
338- }
339- }
340- }
341347}
342348
343349#[ score_testing_macros:: test_mod_with_log]
@@ -348,7 +354,7 @@ mod tests {
348354 fn create_monitor_with_deadlines ( ) -> DeadlineMonitor {
349355 let allocator = ProtectedMemoryAllocator { } ;
350356 let monitor_tag = MonitorTag :: from ( "deadline_monitor" ) ;
351- let inner = DeadlineMonitorBuilder :: new ( )
357+ DeadlineMonitorBuilder :: new ( )
352358 . add_deadline (
353359 DeadlineTag :: from ( "deadline_long" ) ,
354360 TimeRange :: new ( core:: time:: Duration :: from_secs ( 1 ) , core:: time:: Duration :: from_secs ( 50 ) ) ,
@@ -360,14 +366,13 @@ mod tests {
360366 core:: time:: Duration :: from_millis ( 50 ) ,
361367 ) ,
362368 )
363- . build ( monitor_tag, & allocator) ;
364- DeadlineMonitor :: new ( inner)
369+ . build ( monitor_tag, & allocator)
365370 }
366371
367372 fn create_monitor_with_multiple_running_deadlines ( ) -> DeadlineMonitor {
368373 let allocator = ProtectedMemoryAllocator { } ;
369374 let monitor_tag = MonitorTag :: from ( "deadline_monitor" ) ;
370- let inner = DeadlineMonitorBuilder :: new ( )
375+ DeadlineMonitorBuilder :: new ( )
371376 . add_deadline (
372377 DeadlineTag :: from ( "slow" ) ,
373378 TimeRange :: new ( core:: time:: Duration :: from_secs ( 0 ) , core:: time:: Duration :: from_secs ( 50 ) ) ,
@@ -393,8 +398,7 @@ mod tests {
393398 core:: time:: Duration :: from_millis ( 10 ) ,
394399 ) ,
395400 )
396- . build ( monitor_tag, & allocator) ;
397- DeadlineMonitor :: new ( inner)
401+ . build ( monitor_tag, & allocator)
398402 }
399403
400404 #[ test]
@@ -433,7 +437,7 @@ mod tests {
433437 monitor. inner . evaluate ( & mut |monitor_tag, deadline_failure| {
434438 assert_eq ! (
435439 deadline_failure,
436- DeadlineEvalError :: TooEarly ,
440+ DeadlineEvaluationError :: TooEarly . into ( ) ,
437441 "Deadline {:?} should not have failed({:?})" ,
438442 monitor_tag,
439443 deadline_failure
@@ -451,7 +455,7 @@ mod tests {
451455 monitor. inner . evaluate ( & mut |monitor_tag, deadline_failure| {
452456 assert_eq ! (
453457 deadline_failure,
454- DeadlineEvalError :: TooEarly ,
458+ DeadlineEvaluationError :: TooEarly . into ( ) ,
455459 "Deadline {:?} should not have failed({:?})" ,
456460 monitor_tag,
457461 deadline_failure
@@ -477,7 +481,7 @@ mod tests {
477481 monitor. inner . evaluate ( & mut |monitor_tag, deadline_failure| {
478482 assert_eq ! (
479483 deadline_failure,
480- DeadlineEvalError :: TooEarly ,
484+ DeadlineEvaluationError :: TooEarly . into ( ) ,
481485 "Deadline {:?} should not have failed ({:?})" ,
482486 monitor_tag,
483487 deadline_failure
@@ -496,7 +500,7 @@ mod tests {
496500 monitor. inner . evaluate ( & mut |monitor_tag, deadline_failure| {
497501 assert_eq ! (
498502 deadline_failure,
499- DeadlineEvalError :: TooLate ,
503+ DeadlineEvaluationError :: TooLate . into ( ) ,
500504 "Deadline {:?} should not have failed({:?})" ,
501505 monitor_tag,
502506 deadline_failure
@@ -525,7 +529,7 @@ mod tests {
525529 cnt += 1 ;
526530 assert_eq ! (
527531 deadline_failure,
528- DeadlineEvalError :: TooLate ,
532+ DeadlineEvaluationError :: TooLate . into ( ) ,
529533 "Deadline {:?} should not have failed({:?})" ,
530534 monitor_tag,
531535 deadline_failure
0 commit comments