HTTPClient Cache Reuse Without Server Freshness Check in Background Fetch
0 reputation · 08 May 2024, 23:14 UTC
0 reputation · 08 May 2024, 23:14 UTC
The HTTPClient cache in Appcelerator Titanium stores responses keyed by URL and ETag, but does not automatically invalidate on server-side changes unless the request includes Cache-Control headers. On Android 10+, the default max-stale value of 0 disables tolerance for expired entries, triggering immediate freshness checks, yet the interaction between this behavior and background fetch reissues is undocumented. When a background fetch cycle reissues a previously cached request, the framework may reuse the prior response without re-evaluating server freshness, potentially delivering stale data to the user. This behavior varies across TiSDK versions, as earlier releases lack the clearCache API and exhibit different cache eviction policies under memory pressure. The precise conditions under which cached responses are retained versus re-fetched during background fetch remain unresolved, creating uncertainty for applications that require up-to-date data in offline-first scenarios.
32275 reputation · 09 May 2024, 01:55 UTC
There is no confirmed TiSDK/platform combination that guarantees a cached response is reused during background fetch without a server freshness check — and the premise in the question needs untangling. Titanium's HTTPClient is a thin wrapper over the platform HTTP stacks (Android's HTTP layer and iOS's URL loading system), so caching behavior is governed by standard HTTP cache semantics plus whatever request options your code sets, not by a Titanium-specific "background fetch cache mode." Background fetch scheduling and HTTP caching are separate concerns: reissuing a request from a background cycle does not, by itself, force or skip revalidation.
A reissued request returns a cached response without contacting the server when the stored entry is still fresh under the response's Cache-Control or Expires headers (for example, max-age=3600 issued an hour ago means no network traffic at all). ETag normally enters the picture only after an entry is stale, when the cache sends a conditional request (If-None-Match) and the server replies 304 or 200. So "reused without re-evaluating the ETag" is expected behavior for a fresh entry — not a bug, and not specific to background fetch.
None can be named from general knowledge, and you should treat any claim tying this to "Android 10+" or a specific TiSDK line as unverified until reproduced in your environment. What is well established: freshness is decided by response headers and platform cache policy, and Titanium does not document a distinct background-fetch cache path. If you observe reuse without a conditional request, first check whether the original response carried a future max-age or heuristic freshness (a Last-Modified header lets caches heuristically estimate freshness even without explicit Cache-Control).
The "default max-stale=0 on Android 10+" framing likely conflates application-set OkHttp Cache-Control directives with platform defaults — do not assume it describes Titanium behavior. In standard HTTP semantics, the response headers determine cacheability and freshness; request directives like no-cache or max-stale only take effect if your app sets them and the underlying stack honors them. Absence of response Cache-Control does not reliably mean immediate revalidation, because heuristic freshness may apply.
Eviction lowers the chance of later stale reuse simply because entries are gone — but it is not a freshness mechanism. It produces unpredictable misses and refetches, so never reason about data currency from eviction behavior.
no-cache request header where supported, or add a cache-busting query parameter as a last resort).max-age/stale-while-revalidate-style policy, and record a fetch timestamp in your app so you can decide what to show.Because this is version- and device-sensitive, instrument rather than assume:
no-store, no-cache, max-age=0, and a future max-age to separate cacheability from freshness.One diagnostic detail that would sharpen this: the actual response headers (Cache-Control, Expires, ETag, Last-Modified) your server sends. Without them, any observed "stale reuse" can't be attributed to background fetch rather than ordinary freshness.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.