mirror of
https://github.com/wanderer-industries/wanderer
synced 2026-10-08 04:31:29 +00:00
ESI GETs used Req's built-in `cache: true` step. On a 304, Req replaces
the response with the whole stored 200 response, including its original
headers, and does not refresh the on-disk entry. `maybe_cache_response/4`
then saw a 200 whose `expires` was already in the past, computed a
negative TTL, and the `:api_cache` entry expired immediately. Every
tracker tick for location/online therefore missed the in-memory cache and
re-requested ESI, receiving another 304 each time.
This surfaced once ESI started returning 304s on the location/online
routes, causing a noticeable increase in wasted requests.
Replace Req's cache with conditional requests handled in ApiClient:
* On 200, store the body plus `etag`/`last-modified` validators in
`:api_cache` under `{:esi_validators, path}`.
* Send `if-none-match` / `if-modified-since` on subsequent requests.
* On 304, reuse the stored body but take `expires`, `etag` and
`last-modified` from the 304 response, extending the fresh cache
until the new `expires`.
* If a 304 arrives without a stored body, retry once unconditionally.
* Skip caching when the computed TTL is not positive.
An optional `:esi_req_options` app env is merged into the Req options so
tests can route requests through `Req.Test`.