@@ -230,33 +230,52 @@ def find_valid_version(self, timestamp: int) -> Optional[ConfigurationVersion]:
230
230
231
231
:returns: Optional[ConfigurationVersion]: The valid version, or None if not found.
232
232
"""
233
+ # No versions exist
233
234
if not self .versions :
234
235
return None
236
+
237
+ # If no version is cached yet, find and cache the versions for this timestamp
235
238
if self .version is None :
236
239
self .previous_version , self .version , self .next_version = (
237
240
self ._find_versions (timestamp )
238
241
)
239
242
return self .version
240
- if (
241
- self .next_version
242
- and self .next_version .valid_from
243
- and self .next_version .valid_from <= timestamp
244
- ):
245
- self .previous_version , self .version , self .next_version = (
246
- self ._find_versions (timestamp )
247
- )
248
- return self .version
249
- if self .version :
250
- if self .version .valid_from is None :
243
+
244
+ # Check if the next version has become valid (timestamp has moved forward)
245
+ # If so, recalculate all cached versions
246
+ if self .next_version :
247
+ # If next version has no valid_from date, it's always valid
248
+ if self .next_version .valid_from is None :
249
+ self .previous_version , self .version , self .next_version = (
250
+ self ._find_versions (timestamp )
251
+ )
251
252
return self .version
252
- if self .version .valid_from <= timestamp :
253
+ # If next version's valid_from is before or at the timestamp, it's valid
254
+ if self .next_version .valid_from <= timestamp :
255
+ self .previous_version , self .version , self .next_version = (
256
+ self ._find_versions (timestamp )
257
+ )
253
258
return self .version
259
+
260
+ # Check if the current cached version is still valid for this timestamp
261
+ # If version has no valid_from date, it's always valid
262
+ if self .version .valid_from is None :
263
+ return self .version
264
+ # If version's valid_from is before or at the timestamp, it's valid
265
+ if self .version .valid_from <= timestamp :
266
+ return self .version
267
+
268
+ # Fallback: check if the previous version is valid for this timestamp
269
+ # This can happen when messages are out of order and timestamp is before the current version's valid_from
254
270
if self .previous_version :
271
+ # If previous version has no valid_from date, it's always valid
255
272
if self .previous_version .valid_from is None :
256
273
return self .previous_version
274
+ # If previous version's valid_from is before or at the timestamp, it's valid
257
275
if self .previous_version .valid_from <= timestamp :
258
276
return self .previous_version
259
277
278
+ # If cached versions don't match, recalculate all versions for this timestamp
260
279
self .previous_version , self .version , self .next_version = self ._find_versions (
261
280
timestamp
262
281
)
@@ -285,27 +304,45 @@ def _find_versions(
285
304
current_version : Optional [ConfigurationVersion ] = None
286
305
next_version : Optional [ConfigurationVersion ] = None
287
306
307
+ # Iterate through versions in descending order (highest version number first)
308
+ # This ensures we process the most recent versions first
288
309
for _ , version in sorted (
289
310
self .versions .items (), reverse = True , key = lambda x : x [0 ]
290
311
):
312
+ # Handle versions with no valid_from timestamp (always valid)
291
313
if version .valid_from is None :
314
+ # First version with no valid_from becomes the current version
292
315
if current_version is None :
293
316
current_version = version
317
+ return previous_version , current_version , next_version
318
+ # Second version with no valid_from becomes the previous version
294
319
elif previous_version is None :
295
320
previous_version = version
321
+ # Early return since we have current and previous, no next needed for no-timestamp versions
296
322
return previous_version , current_version , next_version
323
+
324
+ # Handle versions that are valid in the future (after the timestamp)
297
325
elif version .valid_from > timestamp :
326
+ # First future version becomes the next version
298
327
if next_version is None :
299
328
next_version = version
329
+ # If we find an earlier future version, it becomes the new next version
300
330
elif (
301
331
next_version .valid_from is not None
302
332
and version .valid_from < next_version .valid_from
303
333
):
304
334
next_version = version
305
- elif current_version is None :
306
- current_version = version
307
- elif previous_version is None :
308
- previous_version = version
309
- return previous_version , current_version , next_version
310
335
336
+ # Handle versions that are valid at or before the timestamp
337
+ else : # version.valid_from <= timestamp
338
+ # First valid version becomes the current version
339
+ if current_version is None :
340
+ current_version = version
341
+ # Second valid version becomes the previous version
342
+ elif previous_version is None :
343
+ previous_version = version
344
+ # Early return since we have found current and previous versions
345
+ return previous_version , current_version , next_version
346
+
347
+ # Return the final state of all three version slots
311
348
return previous_version , current_version , next_version
0 commit comments