Skip to content

feat: persist Remote Config last-known-good - #753

Closed
shameondev wants to merge 23 commits into
codex/restore-tls-verificationfrom
codex/rc-persistent-lkg
Closed

feat: persist Remote Config last-known-good#753
shameondev wants to merge 23 commits into
codex/restore-tls-verificationfrom
codex/rc-persistent-lkg

Conversation

@shameondev

@shameondev shameondev commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Outcome

Adds persistent Last Known Good (LKG) delivery for Remote Configs so a process restart plus transient API/network failure returns the last valid response before falling back to the bundled file. Also exposes durable frozen assignment provenance and serializes user-scope changes so late identify/logout/restore/launch responses cannot cross user boundaries.

Stacked on #752 so the release contains both persistent fallback and restored TLS certificate/hostname verification.

Reliability contract

  • scope cache entries by project key, effective API key, environment, Qonversion user, and context key
  • serialize manager state and validate identity stability before cache, after property flush, before network, and before delivery
  • retain/replay single and list waiters exactly once across identify/logout/restore transitions
  • use network success first, then persistent LKG, then bundled fallback; do not overwrite valid LKG with an oversized or static fallback entry
  • fall back on transient URLSession/DNS/connectivity errors, malformed/empty success responses, and 5xx; never mask cancellation, authentication, or other 4xx
  • validate that single/list responses contain only requested, unique normalized context keys; preserve the authoritative no-config sentinel and remove stale LKG
  • bound the archive to 64 entries / 512 KiB; schema, exception, and semantic enum corruption clear the archive
  • generation-fence disk writes so pre-identity responses cannot repopulate a new user's cache
  • bind every launch response to the user generation at request start and reject superseded responses before mapper/global-state writes
  • make restore scope publication atomic and causally ordered: newer identify/logout/restore intent always wins
  • keep identity/logout terminal commits, cancellation drains, and same-UID invalidation inside one mutation boundary
  • keep launchingFinished false until every concurrent launch ticket terminates and forward the final terminal error when releasing queued work
  • isolate user/entitlement callback queues from manager locks and deliver restore callbacks after internal locks are released
  • expose QONRemoteConfigurationAssignmentTypeFrozen = 2, preserving Unknown for future values and hardening malformed source/group parsing

Verification

  • deterministic red/green tests for same-UID/logout races, re-entrant logout, callback lock inversion, late receipt/historical restore, stale ordinary launches, pending logout refresh, and concurrent launch tickets
  • process-restart, corruption, oversize, response classification, Frozen and malformed-enum regression coverage
  • lint, SPM validation, full XCTest, common checks, and git diff --check

Full XCTest runs in GitHub CI; the local host has Command Line Tools only, without the Xcode platform SDK.

Release fence

Configurator type-3 writes remain disabled until this SDK and the corresponding Android/Sandwich/wrapper releases are in the compatibility matrix.

@shameondev

Copy link
Copy Markdown
Contributor Author

Консолидировано в release-train PR (один PR на репозиторий). Ветка сохранена.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant