@@ -19,25 +19,39 @@ def read_marked_system(device: Device) -> list[str] | None:
1919class SystemFailureTracer (object ):
2020 def __init__ (self ) -> None :
2121 super ().__init__ ()
22- self .on_fail : _Callable [[Device , SuspensionEvent ], None ] = lambda _ , __ : None
23- self .on_recover : _Callable [[Device , SuspensionEvent ], None ] = lambda _ , __ : None
22+ self .on_fail : _Callable [[SuspensionEvent ], None ] = lambda _ : None
23+ self .on_recover : _Callable [[SuspensionEvent ], None ] = lambda _ : None
24+ self .on_device_fail : _Callable [[Device , str | Exception ], None ] = lambda _ , __ : None
25+ self .on_device_recover : _Callable [[Device ], None ] = lambda _ : None
26+ self ._system_failure : dict [str , int ] = {}
2427
2528 def fail (self , device : Device , error : str | Exception ) -> None :
2629 if isinstance (error , Exception ):
2730 error = repr (error )
2831 if not (systems := read_marked_system (device )):
2932 raise RuntimeWarning (f"No system marked for device { device } " )
33+ self .on_device_fail (device , error )
34+ L .error (f"{ device } error: { error } " )
3035 for system in systems :
31- self .on_fail (device , e := SuspensionEvent (context := require_context (), system , error ))
36+ if system not in self ._system_failure :
37+ self ._system_failure [system ] = 0
38+ self ._system_failure [system ] += 1
39+ self .on_fail (e := SuspensionEvent (context := require_context (), system , error ))
3240 context .suspend (e )
33- L .error (f"{ system } error: { error } " )
3441
3542 def recover (self , device : Device ) -> None :
3643 if not (systems := read_marked_system (device )):
3744 raise RuntimeWarning (f"System not marked for device { device } " )
45+ self .on_device_recover (device )
46+ L .debug (f"{ device } recovered" )
3847 for system in systems :
39- self .on_recover (device , SuspensionEvent (require_context (), system , "Recovered" ))
40- L .info (f"{ system } recovered" )
48+ if system not in self ._system_failure :
49+ continue
50+ self ._system_failure [system ] -= 1
51+ if self ._system_failure [system ] > 0 :
52+ continue
53+ self ._system_failure .pop (system )
54+ self .on_recover (SuspensionEvent (require_context (), system , "Recovered" ))
4155
4256
4357SFT : SystemFailureTracer = SystemFailureTracer ()
0 commit comments