Skip to content

feat(cache): cache game/localization versions from /metadata with configurable TTL - #117

Merged
MarTrepodi merged 4 commits into
developfrom
feat/version-cache
Jul 13, 2026
Merged

feat(cache): cache game/localization versions from /metadata with configurable TTL#117
MarTrepodi merged 4 commits into
developfrom
feat/version-cache

Conversation

@MarTrepodi

Copy link
Copy Markdown
Collaborator

Summary

Adds an instance-level version cache so version-less get_game_data(), get_localization(), and get_latest_game_data_version() calls no longer make a fresh /metadata round-trip every time, plus two bug fixes picked up along the way.

Fixes #116

Version cache (8cdd771)

  • Both SwgohComlink and SwgohComlinkAsync now cache latestGamedataVersion and latestLocalizationBundleVersion on the instance for version_cache_ttl seconds (default 3600).
  • Cold-cache lookups single-flight behind a threading.Lock (sync) / asyncio.Lock (async) so concurrent callers don't stampede /metadata.
  • Successful get_game_metadata() calls refresh the cache opportunistically; explicit version arguments always bypass it.
  • Escape hatches: version_cache_ttl=0 restores the previous uncached behavior, math.inf caches for the client lifetime, and invalidate_version_cache() / refresh=True force a re-fetch.

Fix: /metadata payload key (1909912) — fixes #116

get_game_metadata() sent the snake_case client_specs key, but the comlink /metadata request schema requires camelCase clientSpecs and declares additionalProperties: false, so requests with client specs were rejected by the server. Verified against the comlink OpenAPI spec (v0.40.1). The mocked unit tests asserted the wrong key and were updated alongside the fix.

Fix: exception constructor logging (f841fa8)

Constructing a SwgohComlinkException logged an error-level traceback via logger.exception() even for expected, caught validation errors, and emitted NoneType: None tracebacks outside an except block. The constructor override is removed; callers own logging context.

Testing

  • New tests/unit/test_version_cache.py (214 lines) covering TTL expiry, single-flight behavior, opportunistic refresh, explicit-version bypass, invalidation, and refresh=True for both clients.
  • New tests/unit/test_exceptions.py cases asserting constructors no longer log.
  • Existing metadata payload tests updated to assert the correct clientSpecs key.

🤖 Generated with Claude Code

github-actions Bot and others added 4 commits July 12, 2026 18:10
Constructing a SwgohComlinkException logged an error-level traceback via
logger.exception() even for expected, caught validation errors, and calling
it outside an except block emitted 'NoneType: None' tracebacks. Callers own
logging context; the constructor override is removed along with the now-moot
B904 per-file ruff ignore.
The /metadata request schema requires the camelCase 'clientSpecs' key and
declares additionalProperties: false, so the snake_case 'client_specs' key
sent by get_game_metadata() was rejected by the server. Verified against
the comlink OpenAPI spec (v0.40.1).
…figurable TTL

Version-less get_game_data(), get_localization(), and
get_latest_game_data_version() calls previously made a fresh /metadata
round-trip every time. Both clients now cache latestGamedataVersion and
latestLocalizationBundleVersion on the instance for version_cache_ttl
seconds (default 3600). Cold-cache lookups single-flight behind a
threading.Lock (sync) or asyncio.Lock (async), successful
get_game_metadata() calls refresh the cache opportunistically, and
explicit version arguments always bypass it. Set version_cache_ttl=0 to
restore the previous uncached behavior, math.inf to cache for the client
lifetime, or call invalidate_version_cache() / pass refresh=True to force
a re-fetch.
@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Updates to package dependency libraries code testing labels Jul 13, 2026
@MarTrepodi
MarTrepodi merged commit d351759 into develop Jul 13, 2026
15 checks passed
@MarTrepodi
MarTrepodi deleted the feat/version-cache branch July 13, 2026 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code dependencies Updates to package dependency libraries documentation Improvements or additions to documentation testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant