Skip to content

fix(device): reload stale persistent resolved-device entries - #8

Open
xylophonez wants to merge 1 commit into
edgefrom
fix/device-cache-reload
Open

xylophonez wants to merge 1 commit into
edgefrom
fix/device-cache-reload

Conversation

@xylophonez

Copy link
Copy Markdown
Owner

Problem

hb_device_load caches device reference -> generated module atom in the configured loaded-device-store. The default for that store is volatile, but the option accepts ordinary store backends and can be configured as LMDB (or another persistent store) — which is desirable on nodes that want resolved dynamic devices to survive restarts.

After the first VM resolves a dynamic device, a persistent store holds a binary such as _hb_device_<archive-derived-name>. A fresh Erlang VM has neither that generated atom nor its loaded BEAM code. The current cache-hit path calls hb_util:atom/1 (existing-atom conversion), which raises badarg; and even if the atom happens to exist, returning it when its code is not loaded is not a usable cache hit either. A device used from on.start can therefore prevent the restarted node from serving HTTP at all.

Reproduction

  1. Configure loaded-device-store as an LMDB (persistent) store.
  2. Resolve a loadable dynamic device so its <reference> entry is written.
  3. Stop the Erlang VM without deleting the store.
  4. Start a fresh VM against the same store and resolve the same reference.

Observed: list_to_existing_atom raises badarg, surfaced as a failed device resolution / node start. Expected: an entry whose atom or code is absent in this VM is treated as a cache miss, followed by normal trusted-archive resolution and loading.

Fix

Replace the direct hb_util:atom(Bin) match in get_resolved_device/2 with a guarded helper that demotes "name not an existing atom" or "module not loaded" to a cache miss ({error, not_found}), so the surrounding maybe block falls through to the trusted archive path. Fail-safe direction: a stale entry is re-fetched and re-verified, never blindly trusted.

Includes a unit test asserting that a loaded module round-trips and that _hb_device_stale_cache_entry_that_is_not_an_existing_atom returns {error, not_found} without adding an atom.

Single file, no behavioural change for the default volatile store.

A persistent loaded-device-store keeps device-reference -> module-atom
entries across VM restarts, but a fresh VM lacks both the generated atom
and its BEAM code. The cache-hit path's hb_util:atom/1 then raises badarg
(or returns a module whose code is absent), which can stop a restarted
node from serving HTTP when a device is used from on.start.

Demote absent-atom / not-loaded entries to a cache miss via a guarded
loaded_cached_module/1 helper so the maybe block falls through to trusted
archive resolution. Adds a regression test.
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