Skip to content

fix: isolate cold-start prefetch from main URLSession (iOS) + Android cookie/outcome#80

Open
oferRounds wants to merge 1 commit into
margelo:mainfrom
oferRounds:fix/ios-prefetch-session-isolation-main
Open

fix: isolate cold-start prefetch from main URLSession (iOS) + Android cookie/outcome#80
oferRounds wants to merge 1 commit into
margelo:mainfrom
oferRounds:fix/ios-prefetch-session-isolation-main

Conversation

@oferRounds
Copy link
Copy Markdown
Contributor

@oferRounds oferRounds commented Apr 13, 2026

Problem / motivation

On cold start, native autoprefetch (token refresh + queued URLs) and JS-initiated fetch can compete for the same resources. We saw real-world symptoms in a large React Native app:

  • App stuck on the launch loader after login or on repeat launches: critical bootstrap requests never completed in time, or appeared to hang.
  • On iOS, using a single shared URLSession for both autoprefetch and normal traffic meant long-running or stuck prefetch work could saturate the connection pool or otherwise interfere with interactive fetches.
  • The client also awaited an in-flight prefetch on the main fetch path, so a slow or wedged prefetch could block the same URL when JS needed it immediately.
  • Invalid or empty prefetch URLs could still be passed through in some paths, causing noisy failures or wasted work.
  • On Android (Cronet), cookies from the system CookieManager were not consistently attached or updated from responses, so cold-start prefetch and follow-up requests could disagree on auth state.
  • Operators lacked a cheap, plaintext signal for what happened during native cold-start token refresh before JS ran.

This PR addresses those gaps: isolate prefetch on iOS, stop blocking the hot path on pending prefetch, harden URLs and timeouts, improve Android cookie parity, and expose a small debug hook on JS.

Summary

Production-hardening ported from a downstream consumer that currently ships the same logic via patch-package on react-native-nitro-fetch@1.0.0. Ported onto margelo/main; the FetchCache barrier eviction hunk from that patch was omitted here because main already contains that fix.

iOS

  • Add a dedicated prefetchSession (URLSession) for native autoprefetch so prefetch traffic does not share the main session’s connection pool with JS-initiated fetches.
  • Do not block the main fetch path waiting for an in-flight prefetch; fall through and run a fresh request on the main session (prefetch can still complete and warm cache).
  • Default timeouts for requests without timeoutMs and for autoprefetch.
  • Validate autoprefetch URLs with URL(string:) before enqueueing.

Android

  • Attach Cookie header from CookieManager when building Cronet requests (when not already present); store Set-Cookie on redirects and success.
  • Record last cold-start token-refresh outcome in plaintext prefs (aligned with JS key) for debugging.

JS

  • Export getFetchTokenRefreshLastOutcome() (reads the same storage key Android/iOS write).

Testing

  • Maintainers: please run package CI / example app cold start as you normally do.

Refs: downstream patch derived from production cold-start / app-loader investigation.

Made with Cursor

Use a dedicated URLSession for native autoprefetch so slow prefetch work cannot saturate the main session connection pool or block JS-initiated fetches. Skip awaiting an in-flight prefetch on the hot path; issue a fresh request on the main session instead while prefetch completes in the background.

Also: validate autoprefetch URLs, apply default request/prefetch timeouts on iOS, persist last token-refresh outcome for debugging on Android, attach/store cookies for Cronet on Android, and export getFetchTokenRefreshLastOutcome from JS.

Ported from HiBob production patch (react-native-nitro-fetch 1.0.0); FetchCache eviction barrier fix omitted here because it is already on main.

Made-with: Cursor
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