Skip to content

fix(theme): avoid repeated host NIF probes - #108

Merged
GenericJam merged 2 commits into
masterfrom
fix/quiet-host-theme-fallback
Aug 30, 2026
Merged

fix(theme): avoid repeated host NIF probes#108
GenericJam merged 2 commits into
masterfrom
fix/quiet-host-theme-fallback

Conversation

@GenericJam

@GenericJam GenericJam commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • serialize and memoize the first Mob.Theme.color_scheme/0 NIF availability probe
  • return the documented light fallback without retrying a failed host on_load on every call
  • detect a later successful native code load so hot deploys recover the native color-scheme path

Validation

  • strict regression: repeated sequential and concurrent host reads
  • full suite: 1281 passed, 38 excluded
  • format, warnings-as-errors compile, strict Credo, erlfmt, native formatter/harness gates
  • native Android and iOS simulator deploys; 20 repeated RPC reads on each returned the native scheme with availability status

Bead: app-7mu

Cache NIF availability after the first serialized probe while allowing a later native code load to restore the native path.

Bead: clarity-7mu
Route platform, theme updates, and appearance reads through one serialized availability state and isolate deterministic load recovery tests.

Bead: clarity-7mu
@GenericJam

Copy link
Copy Markdown
Owner Author

Addressed the adversarial review in 3fd3df1:

  • platform, set_theme, and color_scheme now share one serialized VM-wide availability state
  • unavailable callers skip native invocation until mob_nif is observably loaded; available-call failures transition back to unavailable
  • isolated subprocess regression forces unknown state, asserts exactly one failed load across 12 concurrent mixed set/color callers, and explicitly cleans persistent state
  • isolated fake-module lifecycle covers unavailable -> loaded -> available -> unloaded -> unavailable -> recovered
  • full suite: 1282 passed, 38 excluded; all static/native harness gates green
  • revised native Android and iOS deployments each passed 20 scheme reads plus Theme.set with shared status available

Ready for rereview.

@GenericJam

Copy link
Copy Markdown
Owner Author

Adversarially reviewed. Approve.

Mechanism verified correct: lock-free persistent_term read in steady state, :global.trans-serialized first probe (12 concurrent callers → exactly one on_load report, proven by the new test), re-probe gated on :code.is_loaded flipping — and the device path can't regress because device NIFs are statically linked (ERL_NIF_INIT + -DSTATIC_ERLANG_NIF on both platforms), so first-load is deterministic and this PR only changes retry-after-failure behavior. Hot-code-push cycle (load→unload→reload) covered by the new recovery test.

Empirical: full-suite 'Failed to load NIF library' warnings 199 → 78 (Theme's own sites fully quiet — focused theme run 17 → 1, and that 1 is the by-design single probe report). Gates: 1282 tests / 0 failures, format, credo --strict, warnings-as-errors all clean. Rebase: branch sits directly on the 0.7.35 tag, no conflicts.

Non-blocking notes: (1) a genuine device NIF failure now logs once then falls back silently forever — an explicit one-shot Logger.warning in mark_nif_unavailable/1 would make that intentional rather than incidental; (2) recovery from :unavailable relies on another caller loading mob_nif — fine given the renderer, worth a comment; (3) the shared nif_call rescues broader than safe_platform/0's old UndefinedFunctionError/ErlangError set — a transient badarg briefly latches :unavailable (self-heals); (4) the remaining 78 warnings are Mob.Device/DNS probes outside this PR's scope — filing a follow-up issue.

Merging.

@GenericJam
GenericJam merged commit 08a8901 into master Aug 30, 2026
4 checks passed
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