Rulebearing Playground Coverage Schemas GitHub

ADR-0063: The cache's run start is also read from the clock that stamps files

Context

A cached run records each input's digest and stamp after its extraction. An input whose modification time is after the run started is recorded as unsettled, so the next run reads it again rather than trusting a digest taken before the edit. The start was read from the system clock, to the nanosecond.

File systems stamp a file with a coarse clock: Windows' ticks about every 16 ms, and Linux stamps from the kernel's coarse clock, which advances once a jiffy (1 to 10 ms). A file edited a few milliseconds after the run started can therefore carry a time a few milliseconds before the start. It is recorded settled, with the digest of the content the run read before the edit. The next run sees the stamp unchanged and serves the stale extraction.

Pull request 53's Windows job found this. The unit test was then made to edit 50 ms after the start, so that it would not depend on the tick. The plan recorded that the fix needed a design: a slack on the comparison closes the gap, but it also marks every file written within the slack before a run as unsettled. Five cache tests that write and then run at once would then miss.

Decision

The start is read twice: by the system clock, and by the clock that stamps files. When a run starts, before it looks at anything, it writes a probe file of its own in the system's temporary folder, reads the file's modification time and removes it (Start::now).

An input counts as modified during the run when any of these holds:

Same clock, same tick: an edit after the start can never carry a time earlier than a file written at the start. An edit stamped in the start's own tick shares the probe's time and is read again, since it cannot be told apart from one made just before the start.

If the probe cannot be written, the system clock alone decides, as before.

Consequences

Alternatives considered

Option Why not
A slack: count anything within 16 ms (or a second) before the start as unsettled Over-reads every file written in the slack window, and fails the cache tests that write and run at once. The probe narrows the window to the one tick that cannot be told apart.
Probe inside the cache folder Adds a file to every user's cache folder that a listing would show (the ESLint plugin's test counts that folder's entries). The temporary folder carries the same clock.
Re-hash every input at record time and compare with the run's read Doubles the hashing of every cached run to close a window of milliseconds.