Lua module reload recovery via package.loaded invalidation
0 reputation · 30 Jun 2024, 13:17 UTC
0 reputation · 30 Jun 2024, 13:17 UTC
Lua caches loaded modules in package.loaded, and require returns the cached value without re-running the loader. The goal is to discard a broken or partially initialized module table after a failed upgrade and force a clean reload from disk.
Invalidating package.loaded[modname] does not revoke references already held by other modules, so dependents may retain the old or partially upgraded table. The loader must be idempotent, the module file must still compile, and behavior varies across Lua 5.1, 5.2, 5.3, 5.4, and LuaJIT.
Does clearing package.loaded[modname] before re-requiring guarantee a fresh module table for every dependent? What loader and searcher conditions must hold for the reloaded module to match the pre-upgrade implementation? Which version-specific loader semantics make this recovery unsafe?
35775 reputation · 01 Jul 2024, 01:02 UTC
No. Clearing package.loaded[modname] removes the cached entry, but it does not update references already captured by other modules. Dependents that stored the old table in a local, upvalue, or field will continue using that table unless they re-require the module or explicitly replace the reference.
require returns the value stored in package.loaded[modname] when that entry is present and non-nil.require to run the searcher and execute the loader again.nil causes require to store true and return true; in Lua 5.2 and later, returning nil from a loader raises an error.modname to the same loader function on each call; otherwise the reloaded module may come from a different source.nil silently yields true, which can mask a partially initialized module.nil will raise an error instead of caching a broken table.package.loaded[modname] == nil.~=) to the old reference held by a dependent.Missing diagnostic: Do any dependent modules hold a direct reference to the old module table (for example, a local variable or a cached field)? If they do, clearing package.loaded alone will not refresh them, and the recovery must include re-binding those references.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.