1212// *******************************************************************************
1313
1414use crate :: common:: {
15- duration_to_u32, hmon_time_offset, Monitor , MonitorEvalHandle , MonitorEvaluationError , MonitorEvaluator , TimeRange ,
15+ duration_to_u32, duration_to_u64, hmon_time_offset, Monitor , MonitorEvalHandle , MonitorEvaluationError ,
16+ MonitorEvaluator , TimeRange ,
1617} ;
1718use crate :: heartbeat:: heartbeat_state:: { HeartbeatState , HeartbeatStateSnapshot } ;
1819use crate :: log:: { error, warn} ;
1920use crate :: protected_memory:: ProtectedMemoryAllocator ;
2021use crate :: tag:: MonitorTag ;
2122use crate :: HealthMonitorError ;
23+ use core:: sync:: atomic:: { AtomicU64 , Ordering } ;
2224use core:: time:: Duration ;
2325use score_log:: ScoreDebug ;
2426use std:: sync:: Arc ;
@@ -100,30 +102,30 @@ impl Monitor for HeartbeatMonitor {
100102 }
101103}
102104
103- /// Time range using [`u32 `].
105+ /// Time range using [`u64 `].
104106#[ derive( ScoreDebug ) ]
105107struct InternalRange {
106- min : u32 ,
107- max : u32 ,
108+ min : u64 ,
109+ max : u64 ,
108110}
109111
110112impl InternalRange {
111113 /// Create range using provided values.
112- fn new ( min : u32 , max : u32 ) -> Self {
114+ fn new ( min : u64 , max : u64 ) -> Self {
113115 assert ! ( min <= max, "provided min is greater than provided max" ) ;
114116 Self { min, max }
115117 }
116118
117119 /// Create range with values offset by timestamp.
118- fn offset ( & self , timestamp : u32 ) -> Self {
120+ fn offset ( & self , timestamp : u64 ) -> Self {
119121 Self :: new ( self . min + timestamp, self . max + timestamp)
120122 }
121123}
122124
123125impl From < TimeRange > for InternalRange {
124126 fn from ( value : TimeRange ) -> Self {
125- let min = duration_to_u32 ( value. min ) ;
126- let max = duration_to_u32 ( value. max ) ;
127+ let min = duration_to_u64 ( value. min ) ;
128+ let max = duration_to_u64 ( value. max ) ;
127129 Self :: new ( min, max)
128130 }
129131}
@@ -139,6 +141,8 @@ pub(crate) struct HeartbeatMonitorInner {
139141 /// Offset is calculated during evaluation in relation to provided health monitor starting point.
140142 monitor_starting_point : Instant ,
141143
144+ start_timestamp : AtomicU64 ,
145+
142146 /// Current heartbeat state.
143147 /// Contains data in relation to [`Self::monitor_starting_point`].
144148 heartbeat_state : HeartbeatState ,
@@ -148,7 +152,7 @@ impl MonitorEvaluator for HeartbeatMonitorInner {
148152 fn evaluate ( & self , hmon_starting_point : Instant , on_error : & mut dyn FnMut ( & MonitorTag , MonitorEvaluationError ) ) {
149153 // Get current timestamp, with offset to HMON time.
150154 let offset = hmon_time_offset ( hmon_starting_point, self . monitor_starting_point ) ;
151- let now = offset + duration_to_u32 ( hmon_starting_point. elapsed ( ) ) ;
155+ let now = offset + duration_to_u64 ( hmon_starting_point. elapsed ( ) ) ;
152156
153157 // Load current monitor state.
154158 let snapshot = self . heartbeat_state . snapshot ( ) ;
@@ -158,15 +162,12 @@ impl MonitorEvaluator for HeartbeatMonitorInner {
158162 // It is necessary to:
159163 // - use offset as cycle starting point.
160164 // - get heartbeat snapshot in relation to zero point.
161- let ( start_timestamp, heartbeat_timestamp) = if snapshot. post_init ( ) {
162- let start_timestamp = snapshot. start_timestamp ( ) ;
163- let heartbeat_timestamp = start_timestamp + snapshot. heartbeat_timestamp_offset ( ) ;
164- ( start_timestamp, heartbeat_timestamp)
165+ let start_timestamp = if snapshot. post_init ( ) {
166+ self . start_timestamp . load ( Ordering :: Relaxed )
165167 } else {
166- let start_timestamp = offset;
167- let heartbeat_timestamp = snapshot. heartbeat_timestamp_offset ( ) ;
168- ( start_timestamp, heartbeat_timestamp)
168+ offset
169169 } ;
170+ let heartbeat_timestamp = snapshot. heartbeat_timestamp ( ) ;
170171
171172 // Get allowed time range as absolute values.
172173 let range = self . range . offset ( start_timestamp) ;
@@ -208,35 +209,39 @@ impl MonitorEvaluator for HeartbeatMonitorInner {
208209 // Heartbeat in allowed state.
209210 else {
210211 // Update heartbeat monitor state with a current heartbeat as a beginning of a new cycle.
211- let _ = self
212- . heartbeat_state
213- . update ( |_| Some ( HeartbeatStateSnapshot :: new ( heartbeat_timestamp) ) ) ;
212+ self . start_timestamp . store ( heartbeat_timestamp, Ordering :: Relaxed ) ;
213+ let _ = self . heartbeat_state . update ( |_| {
214+ let mut snapshot = HeartbeatStateSnapshot :: new ( ) ;
215+ snapshot. set_post_init ( true ) ;
216+ Some ( snapshot)
217+ } ) ;
214218 }
215219 }
216220}
217221
218222impl HeartbeatMonitorInner {
219223 fn new ( monitor_tag : MonitorTag , range : TimeRange ) -> Self {
220224 let monitor_starting_point = Instant :: now ( ) ;
225+ let start_timestamp = AtomicU64 :: new ( 0 ) ;
221226 let heartbeat_state_snapshot = HeartbeatStateSnapshot :: default ( ) ;
222227 let heartbeat_state = HeartbeatState :: new ( heartbeat_state_snapshot) ;
223228 Self {
224229 monitor_tag,
225230 range : InternalRange :: from ( range) ,
226231 monitor_starting_point,
232+ start_timestamp,
227233 heartbeat_state,
228234 }
229235 }
230236
231237 /// Provide a heartbeat.
232238 fn heartbeat ( & self ) {
233239 // Get current timestamp.
234- let now = duration_to_u32 ( self . monitor_starting_point . elapsed ( ) ) ;
240+ let now = duration_to_u64 ( self . monitor_starting_point . elapsed ( ) ) ;
235241
236242 // Set heartbeat timestamp and update counter.
237243 let _ = self . heartbeat_state . update ( |mut state| {
238- let start_ts = state. start_timestamp ( ) ;
239- state. set_heartbeat_timestamp_offset ( now - start_ts) ;
244+ state. set_heartbeat_timestamp ( now) ;
240245 state. increment_counter ( ) ;
241246 Some ( state)
242247 } ) ;
0 commit comments