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