clock
Injectable clock for testable time handling.
This module provides a Clock protocol and implementations that allow time-dependent code to be tested deterministically.
Example usage
Production code¶
from snakesee.state import get_clock
def calculate_elapsed(start_time: float) -> float: return get_clock().now() - start_time
Test code¶
from snakesee.state import FrozenClock, set_clock
def test_elapsed(): clock = FrozenClock(1000.0) set_clock(clock)
assert calculate_elapsed(900.0) == 100.0
clock.advance(50.0)
assert calculate_elapsed(900.0) == 150.0
Classes¶
Clock ¶
Bases: Protocol
Protocol for injectable time sources.
This enables deterministic testing by allowing tests to provide a controlled time source instead of using real wall-clock time.
Source code in snakesee/state/clock.py
ClockUtils ¶
Centralized utilities for clock and duration handling.
This class provides consistent handling of duration calculations, including validation and clock skew detection. It centralizes logic that was previously duplicated in JobInfo.elapsed(), JobInfo.duration(), and RuleTimingStats._time_weighted_mean().
Example
Get validated duration¶
result = ClockUtils.calculate_duration(start_time, end_time, "job foo") if not result.is_valid: logger.warning("Clock skew detected for %s", result.context) return result.value
Or use the elapsed time helper¶
elapsed = ClockUtils.elapsed_since(start_time, context="job bar")
Source code in snakesee/state/clock.py
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | |
Functions¶
age_seconds
staticmethod
¶
age_seconds(timestamp: float, clock: Clock | None = None) -> float
Calculate age in seconds (time since timestamp).
This is a convenience method for calculating how old a timestamp is. The result is always non-negative.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timestamp
|
float
|
Unix timestamp to calculate age for. |
required |
clock
|
Clock | None
|
Optional clock instance (defaults to global clock). |
None
|
Returns:
| Type | Description |
|---|---|
float
|
Age in seconds (>= 0). |
Source code in snakesee/state/clock.py
calculate_duration
staticmethod
¶
calculate_duration(start_time: float, end_time: float, context: str | None = None) -> DurationResult
Calculate duration between two timestamps with validation.
This is the primary method for calculating durations. It handles clock skew by clamping negative durations to zero.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
float
|
Start timestamp (Unix epoch seconds). |
required |
end_time
|
float
|
End timestamp (Unix epoch seconds). |
required |
context
|
str | None
|
Optional description for logging (e.g., "job foo"). |
None
|
Returns:
| Type | Description |
|---|---|
DurationResult
|
DurationResult with validated duration and status. |
Source code in snakesee/state/clock.py
elapsed_since
staticmethod
¶
elapsed_since(start_time: float, context: str | None = None, clock: Clock | None = None) -> DurationResult
Calculate elapsed time since a start timestamp.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
float
|
Start timestamp (Unix epoch seconds). |
required |
context
|
str | None
|
Optional description for logging. |
None
|
clock
|
Clock | None
|
Optional clock instance (defaults to global clock). |
None
|
Returns:
| Type | Description |
|---|---|
DurationResult
|
DurationResult with validated elapsed time and status. |
Source code in snakesee/state/clock.py
validate_duration
staticmethod
¶
validate_duration(duration: float, context: str | None = None) -> DurationResult
Validate a pre-calculated duration value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
duration
|
float
|
Duration value in seconds. |
required |
context
|
str | None
|
Optional description for logging. |
None
|
Returns:
| Type | Description |
|---|---|
DurationResult
|
DurationResult with validated duration and status. |
Source code in snakesee/state/clock.py
DurationResult ¶
Result of a duration calculation with validation status.
This class provides a way to handle duration calculations that may encounter clock skew or other issues without raising exceptions.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
The calculated duration (>= 0, clamped if negative). |
|
raw_value |
The original calculated value before clamping. |
|
is_valid |
True if the duration was valid (non-negative). |
|
context |
Optional context description. |
Source code in snakesee/state/clock.py
FrozenClock ¶
Clock frozen at a specific time for testing.
Useful for testing time-dependent logic without flakiness.
Attributes:
| Name | Type | Description |
|---|---|---|
frozen_time |
The frozen Unix timestamp. |
|
frozen_monotonic |
The frozen monotonic value. |
Example
clock = FrozenClock(1700000000.0) assert clock.now() == 1700000000.0
clock.advance(60.0) # Advance by 1 minute assert clock.now() == 1700000060.0
Source code in snakesee/state/clock.py
Functions¶
__init__ ¶
Initialize with specific frozen times.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frozen_time
|
float | None
|
Unix timestamp to freeze at. Defaults to current time. |
None
|
frozen_monotonic
|
float | None
|
Monotonic value to freeze at. Defaults to 0.0. |
None
|
Source code in snakesee/state/clock.py
advance ¶
Advance the frozen time by the given number of seconds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
float
|
Number of seconds to advance (can be negative). |
required |
monotonic ¶
now ¶
set_monotonic ¶
Set the frozen monotonic value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
float
|
Monotonic value to set. |
required |
set_time ¶
Set the frozen time to a specific timestamp.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timestamp
|
float
|
Unix timestamp to set. |
required |
OffsetClock ¶
Clock with a fixed offset from system time.
Useful for simulating time shifts without fully freezing time.
Attributes:
| Name | Type | Description |
|---|---|---|
offset |
Seconds to add to system time. |
Source code in snakesee/state/clock.py
SystemClock ¶
Default clock implementation using system time.
This is the production implementation that delegates to the standard library's time module.
Source code in snakesee/state/clock.py
Functions¶
get_clock ¶
get_clock() -> Clock
Get the current default clock.
Returns:
| Type | Description |
|---|---|
Clock
|
The currently configured clock instance. |