Skip to content

Scheduler

techrevati.runtime.scheduler

Scheduler / clock abstraction.

Every primitive in the runtime that depends on time accepts a clock function (Callable[[], float] returning monotonic seconds). The Clock protocol below formalizes that contract and adds two helpers production code occasionally needs:

  • wall_now for emitting ISO-8601 timestamps without re-wiring datetime.now;
  • sleep_async as a single hook tests can replace to keep async suites fast.

ManualClock is the canonical test double. It used to live in tests/conftest.py only; promoting it makes the contract reusable in downstream test suites that exercise our primitives.

The functions are intentionally synchronous; the async helper sits alongside as a separate method instead of forcing every clock to be async.

Clock

Bases: Protocol

Injectable time source.

Implementations must be safe for concurrent calls from multiple threads / tasks. The default SystemClock is stateless and obviously safe; ManualClock uses a lock so tests that advance time from a sibling thread don't race.

monotonic

monotonic()

Seconds since an arbitrary fixed epoch; never decreases.

wall_now

wall_now()

Calendar time as a UTC-aware datetime.

sleep_async async

sleep_async(seconds)

Cooperative wait for the given duration.

SystemClock

Default production clock — wraps stdlib time functions.

__call__

__call__()

Compatibility shim — many existing primitives accept a Callable[[], float] clock; SystemClock works wherever such a callable is expected.

ManualClock

ManualClock(start=1000.0, wall_start=None)

Deterministic clock for tests.

monotonic returns the same value until advance / tick move it forward. wall_now keeps a parallel calendar timestamp so tests that round-trip ISO strings have stable output. sleep_async does not actually sleep — it yields control to the event loop once via asyncio.sleep(0) so awaiting tasks make progress, and bumps the monotonic clock by seconds so the primitive under test sees time pass.

advance

advance(seconds)

Move both clocks forward by seconds.

tick

tick(absolute_monotonic)

Set monotonic to a specific value (must be non-decreasing).