Skip to content

Refresh exchange rates cached with a future timestamp - #44

Draft
adambuchweitz wants to merge 1 commit into
typecraft-dev:mainfrom
adambuchweitz:adam/rates-future-timestamp
Draft

adambuchweitz wants to merge 1 commit into
typecraft-dev:mainfrom
adambuchweitz:adam/rates-future-timestamp

Conversation

@adambuchweitz

Copy link
Copy Markdown

Exchange rates are refreshed once their fetchedAt is more than 12 hours old, computed as now - fetchedAt. If currencies.json was written while the clock ran ahead, that age is negative, so the cached rates never count as stale and aren't refreshed until the clock passes that time, which could be months away. The same arithmetic holds off retries and time-zone updates after the clock is set back.

  • Calculator.isStale(at, now, maxAgeMs) treats a time more than five minutes in the future, or one that isn't a number, as stale. refresh() uses it for all three checks: zones, rates and the retry gate.
  • A fetchedAt from the future is dropped when the cache loads, so it doesn't linger in state.

One trade-off: if the clock is behind when the launcher opens (for example before NTP syncs at boot), a valid cache looks like it's from the future and the rates are fetched again. Before, it was kept.

Found while reading #16's rate service, which handled this case.

Testing: node --test tests/*.test.js passes, including new isStale tests in tests/calculator.test.js.

🤖 Generated with Claude Code

The rates are refreshed once their fetchedAt is more than 12 hours old.
If currencies.json was written while the clock ran ahead, now - fetchedAt
is negative, so the cached rates never count as stale and are never
refreshed until the clock passes that time. The same arithmetic holds off
retries and time-zone updates after the clock is set back.

Calculator.isStale treats a time more than five minutes in the future (or
not a number) as stale, and refresh() uses it for all three checks. A
future fetchedAt is dropped when the cache loads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant